malli

https://github.com/metosin/malli :malli:
ikitommi 2021-02-22T08:28:17.023300Z

looking forward for that. I’m watching the guardrails repo, but think that’s going to be much more.

ikitommi 2021-02-22T08:28:55.023900Z

> (extensible, but starting with Clojure spec)

1
borkdude 2021-02-22T08:54:14.024600Z

Yeah, but will be a commercial product, so hard to contribute and see what's going on probably

dharrigan 2021-02-22T11:06:14.025600Z

Looking forward to the new function schema - just saw the tweet!

👍 1
ikitommi 2021-02-22T11:53:11.038100Z

@emccue Malli is a dynamic schema/type system, it’s not a static type system. tools like clj-kondo and typed clojure can do static analysis, maybe copilot too? Would love to see tooling get better and happy to help, but no time or skills to do anything non-trivial except to integrate into existing tooling. My point was that resolving fn arity using generative testing or 3rd party tools (clj-kondo) is a hard way to do something that would be easy to do in the core language itself. With core clojure: does a ring middleware chain would work for an async (3) arity? run and see if it throws arityexception 😞

ikitommi 2021-02-22T11:55:33.039500Z

I’m hope and think we’ll see great new developer tooling for clojure in 2021, from the community.

🤞 1
ikitommi 2021-02-22T14:44:29.041700Z

added more benchmarks to repo, parsing vs spec:

;; 44µs
(let [spec (s/* (s/cat :prop string?,
                       :val (s/alt :s string?
                                   :b boolean?)))
      parse (partial s/conform spec)]
  (cc/quick-bench
    (parse ["-server" "foo" "-verbose" "-verbose" "-user" "joe"])))

;; 2.5µs
(let [schema [:* [:cat*
                  [:prop string?]
                  [:val [:alt*
                         [:s string?]
                         [:b boolean?]]]]]
      parse (m/parser schema)]
  (cc/quick-bench
    (parse ["-server" "foo" "-verbose" "-verbose" "-user" "joe"])))

Jakub Zika 2021-02-22T16:23:13.043100Z

Hi guys, I am trying to generate some random date with (mg/generate inst?) but i am not sure how :seed or :size works here. I am getting 1969 or 1970 in 99% cases. How to get a date like any >1980? Thanka dwh-replicator.database> (mg/generate inst? {:seed 20}) ;; => #inst "1970-01-01T00:00:00.000-00:00" dwh-replicator.database> (mg/generate inst? {:seed 42}) ;; => #inst "1970-01-01T00:00:00.000-00:00"

pithyless 2021-02-22T16:55:28.049300Z

@jakub.zika-extern there's a good talk that explains how :seed and :size interact when writing custom generators. It even mentions the datetime problem @ 31:54. https://youtu.be/F4VZPxLZUdA?t=1911 1. The proposed solution in the talk is a custom generator that splits the datetime into separate domain bits (year / month / day / etc.) 2. A different solution (as seen e.g. https://github.com/nasa/Common-Metadata-Repository/blob/master/common-lib/src/cmr/common/test/test_check_ext.clj#L255-L257) is to change the way you choose an initial seed integer (that is used to coerce to date).

Jakub Zika 2021-02-22T16:56:18.049700Z

Thank you!

Alex Whitt 2021-02-22T18:07:22.050300Z

Would anyone like to jump on this discussion thread I created on the subreddit? (I'd prefer to keep it there so it doesn't disappear behind Slack's paywall) https://www.reddit.com/r/Clojure/comments/lpv8ok/spec_vs_malli/

🔥 3
Jakub Zika 2021-02-22T21:14:17.050700Z

I am mapping DB types to clojure types, so varchar(255) goes to [string? {:min 0 :max 255}] etc. I am using these derived schemas to: 1. validate data : (malli/validate [string?] "hoy") 2. generate sample data : (malli.generator/generate [string?]) When I will go for custom generators then I will have to create new validators, correct?

pithyless 2021-02-22T21:19:40.051Z

You'll need to pass in the custom generator to the spec (not necessarily when validating, but at the very least wen generating sample data).

👍 1
pithyless 2021-02-22T21:20:28.051200Z

so instead of

[string? {:min 0 :max 255}]
you'll have to wrap it, eg:
[:and {:gen/elements ["kikka" "kukka" "kakka"]} [string? {:min 0 :max 255}]]

pithyless 2021-02-22T21:20:58.051400Z

where you use one of :gen/elements, :gen/gen, :gen/fmap, etc.

pithyless 2021-02-22T21:25:18.051600Z

^ I think you might even be able to just change the default :gen/gen of the specific type by modifying the malli registry globally (but then you're changing it for everything... which has its own issues ;))

pithyless 2021-02-22T21:26:58.051900Z

OR, perhaps make a custom registry where you override the :gen/gen for the basic types you're interested in (e.g. instant); and then pass in the custom registry only when generating sample data