Fork me on GitHub
#malli
<
2021-02-21
>
ikitommi15:02:28

added more info on function schema explain:

(def MyFunctionSchema
  (m/schema
    [:function
     [:=> [:cat :int] :int]
     [:=> [:cat :int :int [:* :int]] :int]]
    {::m/function-checker mg/function-checker}))

(m/explain
  MyFunctionSchema
  (fn
    ([x] x)
    ([x y & zs] (apply max x y zs))))
; => nil

(m/explain
  MyFunctionSchema
  (fn
    ([x] x)
    ([x y & zs] (str (apply max x y zs)))))
;{:schema [:function 
;          [:=> [:cat :int] :int] 
;          [:=> [:cat :int :int [:* :int]] :int]],
; :value #object[],
; :errors (#Error{:path [],
;                 :in [],
;                 :schema [:function 
;                          [:=> [:cat :int] :int] 
;                          [:=> [:cat :int :int [:* :int]] :int]],
;                 :value #object[],
;                 :check ({:total-nodes-visited 2,
;                          :depth 1,
;                          :pass? false,
;                          :result false,
;                          :result-data nil,
;                          :time-shrinking-ms 0,
;                          :smallest [(0 0)],
;                          :malli.generator/explain-output {:schema :int,
;                                                           :value "0",
;                                                           :errors (#Error{:path []
;                                                                           :in []
;                                                                           :schema :int
;                                                                           :value "0"})}})})}

👍 3
ikitommi15:02:16

really happy how good the function schemas are now, but still - it’s just elegant (and slow) way to verify things at runtime, e.g. not a type system.

borkdude15:02:38

compared to clojure.spec, how slow?

ikitommi15:02:13

the sequence schemas are at least an order of magnitude faster than spec in initial tests. Full function verification uses test.check, I think that dominates, and quess they are about the same.

ikitommi15:02:09

but, having arity info available for fns at runtime (in clojure.core) would help to see that fns are correct on arity, without testing it and getting arityexceptions - costs a lot.

borkdude16:02:04

Maybe you can combine that with static analysis (e.g. from clj-kondo)?

ikitommi18:02:50

I guess it could be done using a clj-kondo hook? with defaults, the test.check runs 19ms for a function on my machine. that’s 500 funcs per sec (on 1 core?). errors are faster, the given example fails fast on invalid return, under 1ms.

borkdude20:02:27

I mean: > but, having arity info available for fns at runtime (in clojure.core) would help to see that fns are correct on arity, without testing it and getting arityexceptions - costs a lot. You could use clj-kondo to find the correct arities perhaps

ikitommi18:02:42

i believe it could be made faster, less iterations on arguments etc.

ikitommi18:02:27

[metosin/malli "0.3.0-SNAPSHOT"] has the stuff in.

🎉 6
ikitommi19:02:03

with 10 iterations, it drops to 0.3ms per fn.'

emccue20:02:32

> e.g. not a type system.

emccue20:02:02

for me, it would serve much the same purpose i'd think

emccue20:02:39

or rather - the same workflow

emccue20:02:49

maybe i'm missing a worldview though

borkdude21:02:20

Btw, this sounds interesting, but I haven't heard anything about it yet: https://www.fulcrologic.com/copilot