Fork me on GitHub
#malli
<
2023-08-14
>
Joel04:08:06

Is there a way to get the type information in regard to a function?

(defn square [x] (* x x))
(m/=> square [:=> {:registry {:a :int}} [:cat :a] nat-int?])
How do I “grab” input/output for square as I’d like to use it elsewhere?

Joel04:08:31

I got as far as (m/function-schemas), but I’d like to ascertain the input/outputs for square

ikitommi05:08:52

You can ask m/children on the schema or call m/ast on it and use the named keys on the result (I recall :input & :output.

🙂 2
ikitommi05:08:26

Curious, what is your use case here?

Joel13:08:22

I’m using Malli to generate data for Pathom, in particular the inputs/outputs in this case. So what I’m really interested in is the registry keywords.

Joel14:08:52

To look-up square in the map, this works, but I’m guessing there’s a better “trick”?

(get (get (m/function-schemas) (symbol (namespace `square))) 'square)

ikitommi06:08:35

Does someone have good arguments for or against the correctness on how :or is decoded now: https://github.com/metosin/malli/issues/910#issuecomment-1676768588

steveb8n01:08:24

I would like to comment but haven’t been affected by this so cannot without more context. if you provide context, I’ll try to add my opinion

jasonjckn04:08:03

my 2 cents I would avoid #1 , because it's not very nice mathematically

(def T (mt/transformer {:name :math}))

(def S1 [:map {:closed true, :decode/math #(assoc % :b 'bad-input)}
         [:a :int]
         [:b :int]])
(def S2 [:map {:closed true, :decode/math #(assoc % :a 'bad-input)}
         [:a :int]
         [:b :int]])

(def I {:a 4, :b 5})

(m/decode S1 I T) ;=> {:a 4, :b bad-input}
(m/decode S2 I T) ;= {:b 4, :a bad-input}

(m/decode [:or S1 S2] I T)  ;=> {:a 4, :b 5}
S1 would never validate value I transformed S2 would never validate value I transformed Yet the S1 ∪ S2 validates value I ‘transformed’ by virtue of the ‘transformation’ being a no-op I may have a use case that's too contrived to explain, but in theory it could hit this, (in practice probably not), and #1 would be the wrong choice. I like both #2 and #3, my intuition slightly prefers #3. As a side note, could you just produce an error, is that a 4th choice. In stricter functional implementations of these 'bijection-like' transformations, when you transform from type A into type B, the return value is either (1) of type B or (2) an error of some kind, the untransformed values are bit dangerous, as it can accidentally get validated as B, when in fact untransformed values of type A just look a bit like B in pathological cases, if that makes sense .

ikitommi09:08:54

Thanks @U0J3J79FE for the long answer! Few comments: • goal of decode is to produce valid values, so all cases where decode breaks it are kinda wrong • I agree on 1 being wrong • m/coerce does both decode & validate • I'm also leaning also towards 3 (today)

🙌 2