Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New destructuring in Clojure 11: Keyword argument functions now also accept maps #605

Open
NoahTheDuke opened this issue Dec 27, 2021 · 4 comments
Labels
enhancement New feature or request

Comments

@NoahTheDuke
Copy link
Contributor

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]))
@ikitommi ikitommi added the enhancement New feature or request label Dec 27, 2021
@ikitommi
Copy link
Member

Indeed, we need a better way for this.

@ikitommi
Copy link
Member

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]))

@ikitommi
Copy link
Member

ikitommi commented Dec 29, 2021

... 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?

@ikitommi
Copy link
Member

#606

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants