malli
malli copied to clipboard
New destructuring in Clojure 11: Keyword argument functions now also accept maps
As discussed on slack, Clojure now supports destructuring maps as key-value pairs in parameter lists: [& {:as m :keys [id before after]}] can be used as both (f {:id 1 :before 2 :after 3}) and (f :id 1 :before 2 :after 3). To use this when writing a schema requires doubling up on the definition:
(def f
(m/schema
[:=>
[:cat
[:or
[:and
[:map
[:id qualified-keyword?]
[:before {:optional true} fn?]
[:after {:optional true} fn?]]
[:fn (fn [{:keys [before after]}] (or before after))]]
[:and [:catn
[:id [:cat [:= :id] qualified-keyword?]]
[:before [:? [:cat [:= :before] fn?]]]
[:after [:? [:cat [:= :after] fn?]]]]
[:fn (fn [[_ & args]] (pos? (count args)))]]]]
:any]))
Indeed, we need a better way for this.
could compress that into:
(def f
(m/schema
[:=>
[:cat
[:and
[:map-like
[:id qualified-keyword?]
[:before {:optional true} fn?]
[:after {:optional true} fn?]]
[:fn (fn [{:keys [before after]}] (or before after))]]]
:any]))
... currently working an a (schematized) destructuring support for malli, generating:
(ms/schema '[a b [c & {:keys [c e] :as ce}] & {:keys [f g] :as fg}])
;[:cat
; :any
; :any
; [:maybe
; [:cat
; [:? :any]
; [:altn
; [:map [:map
; [:c {:optional true} :any]
; [:e {:optional true} :any]]]
; [:args [:* [:alt
; [:cat [:= :c] :any]
; [:cat [:= :e] :any]]]]]]]
; [:altn
; [:map [:map
; [:f {:optional true} :any]
; [:g {:optional true} :any]]]
; [:args [:* [:alt
; [:cat [:= :f] :any]
; [:cat [:= :g] :any]]]]]]
... with that, you would get this schema out from your function:
(ms/schema '[& {:as m :keys [id before after]}])
;[:cat
; [:altn
; [:map [:map
; [:id {:optional true} :any]
; [:before {:optional true} :any]
; [:after {:optional true} :any]]]
; [:args [:*
; [:alt
; [:cat [:= :id] :any]
; [:cat [:= :before] :any]
; [:cat [:= :after] :any]]]]]]
would that be useful enough for your actual case?
#606