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"
@ikitommi You made my day ! I never tried any benchmark on my lib, I did not know it was faster than Clojure Spec 😃
:awesome:
cool :)
@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
This is for the ClojureD-demoed functionality
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.
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
@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.
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?]]]
cc/ @borkdude
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’