malli

https://github.com/metosin/malli :malli:
ikitommi 2020-10-17T01:39:11.218100Z

@jarvinenemil are you using m/validator or m/validate? the latter is a convenience fn for one-shot things: if given schema syntax, for every call, it parses it, creates the Schema instance tree and creates a pure validator for it and runs it once and throws it away. m/validator returns that pure validation function of x -> boolean , so if you can keep that, you pay for the parsing & optimizing just once.

ikitommi 2020-10-17T01:40:18.219500Z

same applies to m/explain vs m/explainer, m/decode vs m/decoder etc.

ikitommi 2020-10-17T01:45:48.224100Z

at best, given a deeply nested schema with 1k fields, the m/decoder can return a indentity function if there are no decoding functions mapped to any of the fields or structure in general. Can't get much faster than that ๐Ÿ˜‰

dangercoder 2020-10-17T09:55:12.225900Z

@ikitommi I did a one off using validate. validator was just what I was looking for, thanks!

ikitommi 2020-10-17T14:15:34.226300Z

curious about the perceived perf gains, hopefully many orders of magnitude..

ikitommi 2020-10-17T14:16:39.227Z

WIP, https://github.com/metosin/malli/pull/283:

(def registry (merge (m/default-schemas) (mu/schemas)))

(def Merged
  (m/schema
    [:merge
     [:map [:x :string]]
     [:map [:y :int]]]
    {:registry registry}))

Merged
;[:merge
; [:map [:x :string]]
; [:map [:y :int]]]

(m/deref Merged)
;[:map 
; [:x :string] 
; [:y :int]]

(m/validate Merged {:x "kikka", :y 6})
; => true

ikitommi 2020-10-17T14:19:42.228700Z

just :merge , :union and :select-keys now, should be easy to add more, with the util helpers. current Schema impls in malli.util:

(defn -merge [] (-util-schema {:type :merge, :f (-reducing merge)}))
(defn -union [] (-util-schema {:type :union, :f (-reducing union)}))
(defn -select-keys [] (-util-schema {:type :select-keys, :min 2, :max 2, :f (-applying select-keys)}))

sparkofreason 2020-10-17T14:24:36.228900Z

Looks to be pretty straightforward. I've done this with spec before. There were two headaches there, one being the lack of a public data representation for specs, second being opaque predicates. In the latter case we used test.check to generate examples and tried to infer from that. I think you do the same thing here, but leveraging malli's inference.

dangercoder 2020-10-17T15:02:31.229100Z

Using validate (cc/quick-bench (m/validate schema {})) Evaluation count : 6 in 6 samples of 1 calls. Execution time mean : 21.971360 sec Execution time std-deviation : 2.848014 sec Execution time lower quantile : 20.065855 sec ( 2.5%) Execution time upper quantile : 26.840086 sec (97.5%) Overhead used : 7.984810 ns Using validator (cc/quick-bench (validator {})) Evaluation count : 31504632 in 6 samples of 5250772 calls. Execution time mean : 12.055681 ns Execution time std-deviation : 0.575152 ns Execution time lower quantile : 11.599548 ns ( 2.5%) Execution time upper quantile : 12.803005 ns (97.5%) Overhead used : 7.984810 ns

ikitommi 2020-10-17T15:19:08.229400Z

that's 9 orders of magnitude ๐Ÿ˜ฎ๐Ÿ˜ฎ๐Ÿ˜ฎ . Are you starting a power plan while creating the schema as it takes 20 seconds???

ikitommi 2020-10-17T15:21:44.229600Z

anyway, good reason to cache the validator :)

dangercoder 2020-10-17T15:21:45.229800Z

I converted a excel-sheet from business people to a malli schema so I can convert the malli schema to a json-schema that can be used from several languages ๐Ÿ˜„

1๐Ÿ‘
dangercoder 2020-10-17T15:28:46.230400Z

I anonymized the fields and havent added regexp yet but just to give u an idea on how big this thing is. @ikitommi I did not decide this, the real world is sometimes a bit messy ๐Ÿ˜„.

jfntn 2020-10-17T17:04:23.234200Z

๐Ÿ‘‹ Iโ€™m looking for a way to use an accumulator during a schema walk.

1๐Ÿ‘‹
2020-10-19T14:59:07.266400Z

There might be a way to bridge Specter and Malli for that purpose.

jfntn 2020-10-17T17:04:33.234400Z

Thatโ€™s easy to hack from the outside in with say an atom but I was wondering if there is cleaner way to do this from the inside out instead?

jfntn 2020-10-17T17:05:31.234600Z

It seems like itโ€™d be possible to reify a Walker that expects the walk fn to return [schema context] and merges the returned context into the options to pass to the next stepโ€ฆ

ikitommi 2020-10-17T17:40:50.235Z

yes, you should implement a custom Walker. find-first might be a good example for that: https://github.com/metosin/malli/blob/master/src/malli/util.cljc#L37-L51

ikitommi 2020-10-17T17:41:39.235300Z

or: subschemas: https://github.com/metosin/malli/blob/master/src/malli/util.cljc#L150-L163

jfntn 2020-10-17T18:05:32.235600Z

Thanks for the pointers!

jfntn 2020-10-17T18:06:01.235800Z

I guess doing this without some atom would require some kind of state monad so I think Iโ€™ll stick with your examples ๐Ÿ˜‚

ikitommi 2020-10-17T18:21:14.236Z

if you get a generic accumulating walker, might be a good example in https://github.com/metosin/malli/blob/master/docs/tips.md.

mike_ananev 2020-10-17T18:45:02.236800Z

@ikitommi can I have docstring for spec in swagger output?

ikitommi 2020-10-17T19:21:36.237700Z

@mike1452 what kind of docstring are you looking for? :title, :description and :default are automatically copied to both JSON Schema and Swagger.

ikitommi 2020-10-17T19:23:02.238800Z

JSON Schema references