malli

https://github.com/metosin/malli :malli:
ikitommi 2020-09-07T06:33:41.136700Z

first spike of heterogenous sequences, aka “regex schemas”. Looked into seqexp, clojure.spec and minimallist for inspiration. Slicing a [1 2 3 "4" "5" 6 7 8 9 "10"] sequence with spec-equivalient:

(s/cat :1 (s/+ int?)
       :2 (s/+ string?)
       :3 (s/+ int?)
       :4 (s/+ string?))
in malli, it would be:
[:catn
  [:1 [:+ int?]]
  [:2 [:+ string?]]
  [:3 [:+ int?]]
  [:4 [:+ string?]]]
or anonymus (uses vector indexes as keys)
[:cat
  [:+ int?]
  [:+ string?]
  [:+ int?]
  [:+ string?]]
some silly perf numbers with 10000 & time (and intermediate results):
Malli:
{:1 [1 2 3], :2 ["4" "5"], :3 [6 7 8 9], :4 ["10"]}
"Elapsed time: 35.535477 msecs"

Minimallist:
{:1 [1 2 3], :2 ["4" "5"], :3 [6 7 8 9], :4 ["10"]}
"Elapsed time: 386.464772 msecs"

Seqexp:
{:rest (), :match (1 2 3 "4" "5" 6 7 8 9 "10"), :1 (1 2 3), :2 ("4" "5"), :3 (6 7 8 9), :4 ("10")}
"Elapsed time: 686.08428 msecs"

Clojure.Spec:
{:1 [1 2 3], :2 ["4" "5"], :3 [6 7 8 9], :4 ["10"]}
"Elapsed time: 879.329458 msecs"

🔖 1
🙂 1
2020-09-09T05:38:15.169Z

@ikitommi You made my day ! I never tried any benchmark on my lib, I did not know it was faster than Clojure Spec 😃

ikitommi 2020-09-10T18:06:54.190500Z

:awesome:

borkdude 2020-09-07T09:36:52.138700Z

cool :)

borkdude 2020-09-07T10:05:32.140200Z

@ikitommi I think this new clj-kondo feature can help with annotations generated by malli in some other config file: https://github.com/borkdude/clj-kondo/issues/992 Users can e.g. use {:config-paths ["malli-types"]}. If malli then spits out the type information in .clj-kondo/malli-types/config.edn, then it will work

borkdude 2020-09-07T10:05:52.140700Z

This is for the ClojureD-demoed functionality

borkdude 2020-09-07T10:06:36.141100Z

I'm also considering a similar tool for clojure spec which inspects specs at runtime and then spits out a file. Maybe there could also be a CIDER middleware which populates things there as you eval code.

borkdude 2020-09-07T10:33:12.141700Z

but if malli is going to have a defn like macro, I think making built-in functionality for it would also be cool. can we do this without depending on malli itself for keeping the dependencies of clj-kondo lean? e.g. it also doesn't depend on schema, it only recognizes the syntax

ikitommi 2020-09-07T12:47:21.153Z

@borkdude good stuff. yes, the planned m/defn can emit the clj-kondo format directly, it’s a great start. Will keep an eye on your spec-tooling work too.

2020-09-07T20:43:04.155600Z

Really looking forward to the m/defn support! I forked aave to add ClojureScript support and m/humanize-d errors recently and am adding in a few additional things — I’ll try to comment in the m/defn threads once they’re live to see whether any of the features added can make it across when the time comes. In particular, I’m binding up parameter and return types together (rather than separately), so that :multi / :or specs can be used as a poor-man’s (although runtime-dispatched) facsimile of overloading. i.e.

[[[:vector int?] => [:map-of int? string?]]
 [[:vector string?] => [:map-of string? int?]]]
translates to
[:or [:tuple [:vector int?] [:map-of int? string?]]
     [:tuple [:vector string?] [:map-of string? int?]]]

2020-09-07T20:43:50.156Z

cc/ @borkdude

2020-09-07T20:45:26.157Z

I’m also excited to use [:multi {:dispatch …}] instead of [:or] (the above are or-ed together), to see whether dispatch to a particular signature can be more sophisticated than simply ‘first matching signature’