malli

roklenarcic 2025-04-24T18:11:19.926259Z

What’s the difference between encode/decode parse/unparse?

2025-04-24T23:00:59.801209Z

I see encode as a more general parse, in that you could probably implement parse in terms of encode.

2025-04-24T23:03:14.008489Z

Maybe you'd need to combine it with validate.

2025-04-24T23:05:16.348069Z

parse is useful if you want more information about why a value is valid. It's sort of the dual of m/explain, which gives information about why value is invalid.

2025-04-24T23:07:49.903059Z

encode is useful for transforming values into other formats and back.

2025-04-24T23:17:40.437829Z

encode is very powerful in comparison to parse. If you want to do something other than just figure out which :orn branch was picked to validate a value, you probably want to look into encode.

2025-04-24T23:20:00.293019Z

(m/parse [:orn [:left :any] [:right :any]] :asdf)
;=> #malli.core.Tag{:key :left, :value :asdf}
(m/unparse [:orn [:left :any] [:right :any]] #malli.core.Tag{:key :left, :value :asdf})
;=> :asdf

roklenarcic 2025-04-25T06:29:30.196209Z

Thanks

Samuel Ludwig 2025-04-24T21:57:40.308709Z

i feel silly asking this, but what does the :size flag do when using mg/generate?

2025-04-24T22:18:12.685049Z

size is an internal test.check value that is used to control the "size" of generators. This means different things for different generators. it starts small and increases as the test demands larger input values. Maybe shrinking uses it to reverse the process, but I don't know how shrinking works.

❤️ 1
➕ 1
Samuel Ludwig 2025-04-24T22:20:25.040699Z

got you, makes sense then why i usually saw it used most-often along-side :seed in the malli README

Samuel Ludwig 2025-04-24T22:03:00.681459Z

ah, I tracked it down to clojure.test.check.generators, but uh, this does not clear much up for me

Samuel Ludwig 2025-04-24T22:10:24.896379Z

Well, I ask because I'm trying to generate a spec defined as a [:sequential <something>], and I'd like to be able to explicitly generate something matching that spec with X elements was hoping for something like (mg/generate [:sequential int?] {:magical-size-option 4}) => [1 3 -2 67]

2025-04-24T22:14:49.634809Z

[:sequential {:gen/min 4 :gen/max 4} int?]

Samuel Ludwig 2025-04-24T22:14:59.263829Z

ahhhhhhhhh

Samuel Ludwig 2025-04-24T22:15:12.718989Z

also better for the ad-hoc update-properties

Samuel Ludwig 2025-04-24T22:16:44.823949Z

i'd prefer to not hard-code the generated size, as I'm trying to restrict the size so that it matches the count of another variably sized sequence

2025-04-24T22:21:06.693409Z

You may need to write your own generator for the outer-most thing and use gen/fmap.

2025-04-24T22:21:16.997249Z

Please provide more details if you can.

Samuel Ludwig 2025-04-24T22:24:39.790889Z

this behaves perfectly for my use-case

(defn sized-gen [spec size]
  (mg/generate (mu/update-properties spec assoc :gen/min size :gen/max size)))
which i would use as
(sized-gen <my-spec> (count <some-sequence>))

Samuel Ludwig 2025-04-24T22:25:11.288399Z

(function-name certainly not final), im just using this for futzing around in a devfile

Samuel Ludwig 2025-04-24T22:27:05.725419Z

appreciate the info otherwise! o/

👍 2
escherize 2025-04-24T22:57:50.207969Z

I might be late to the party but I think you could use tuple for this, too

escherize 2025-04-24T22:58:46.926699Z

e.g. (mg/generate [:tuple int? int? int?])

escherize 2025-04-24T22:59:34.156829Z

(defn sized-gen [mschema n] 
  (mg/generate (into [:tuple] (repeat n mschema))))

(sized-gen :string 2)
;; => ["90S1" "G7G3j1a9O61l89U3rXj1rstbTY9"]

escherize 2025-04-24T22:59:38.236589Z

🤷‍♂️

Samuel Ludwig 2025-04-24T23:00:40.039509Z

Well the goal was that I could take an existing :sequential spec, and purely for testing purposes generate a sequence that otherwise matches the spec, but only contains X elements

Samuel Ludwig 2025-04-24T23:02:39.977849Z

(I would rarely be using [:sequential ...] verbatim here, and would really just be referencing an existing spec in another namespace)

escherize 2025-04-24T23:02:57.192339Z

hack, but:

(first (mc/children [:sequential {:min 5} :string]))
;; => :string

escherize 2025-04-24T23:03:19.616669Z

I think that ambrose's answer is good

Samuel Ludwig 2025-04-24T22:14:51.591949Z

this is the best i've got so far

(mg/generate (mu/update-properties [:sequential int?] assoc :min 4 :max 4))