Fork me on GitHub
#malli
<
2022-01-08
>
ikitommi20:01:08

Given a Var:

(defn -instrument
  "Takes an instrumentation properties map and a function and returns a wrapped function,
   which will validate function arguments and return values based on the function schema
   definition. The following properties are used:

   | key       | description |
   | ----------|-------------|
   | `:schema` | function schema
   | `:scope`  | optional set of scope definitions, defaults to `#{:input :output}`
   | `:report` | optional side-effecting function of `key data -> any` to report problems, defaults to `m/-fail!`
   | `:gen`    | optional function of `schema -> schema -> value` to be invoked on the args to get the return value"
  ([props]
   (-instrument props nil nil))
  ([props f]
   (-instrument props f nil))
  ([{:keys [scope report gen] :or {scope #{:input :output}, report -fail!} :as props} f options]
   ...
a simple schema inferrer:
(md/infer #'m/-instrument {::md/sequential-maps false})
;[:function
; [:=> [:cat :any] :any]
; [:=> [:cat :any :any] :any]
; [:=>
;  [:cat [:map
;         [:scope {:optional true} :any]
;         [:report {:optional true} :any]
;         [:gen {:optional true} :any]] :any :any]
;  :any]]

ikitommi20:01:48

also can read the plumatic hints. Could add it to read also normal Clojure typehints.

ikitommi20:01:26

it can parse both the source code and the :arglists meta (both are described as malli sequence schemas). As we can create clj-kondo hints too, now we can do Var -> Malli -> Clj-kondo for free as in 🍺

ikitommi20:01:29

it also understands the new Clojure keyword-ags-as-maps thing and the maps-as-sequence.

ikitommi20:01:35

this is the real schema for it:

(md/infer #'m/-instrument)
;[:function
; [:=> [:cat :any] :any]
; [:=> [:cat :any :any] :any]
; [:=>
;  [:cat
;   [:altn
;    [:map [:map 
;           [:scope {:optional true} :any] 
;           [:report {:optional true} :any] 
;           [:gen {:optional true} :any]]]
;    [:args
;     [:schema [:* [:alt 
;                   [:cat [:= :scope] :any] 
;                   [:cat [:= :report] :any] 
;                   [:cat [:= :gen] :any] 
;                   [:cat :any :any]]]]]]
;   :any
;   :any]
;  :any]]