or a macro (defmacro defkargs [name destrt & body] `(clojure.core/defn ~name ([] (~name {})) ([a# b# & {:as r#}] (~name (clojure.core/assoc r# a# b#))) ([~destrt] ~@body)))
(defkargs kargs-test {:keys [some me]} (when (and some me) (+ some me))) (and (= (kargs-test :some 1 :me 2) (kargs-test {:some 1 :me 2}) 3) (= (kargs-test) nil)) On Friday, March 13, 2015 at 1:46:08 PM UTC-4, Dylan Butman wrote: > > Late chime in...how about both? > > (defn kargs > ([] (kargs {})) > ([a b & {:as r}] > (kargs (assoc r a b))) > ([a] a)) > > On Thursday, May 1, 2014 at 12:21:03 AM UTC-4, Jim Crossley wrote: >> >> Oh, right. (f m) instead of (apply f [m]). Duh. >> >> >> On Wed, Apr 30, 2014 at 11:15 PM, Colin Fleming <colin.ma...@gmail.com> >> wrote: >> >>> I think it would because in that case you'd just pass your arg map >>> straight through rather than having to reconstruct it. So if you weren't >>> passed :y in g (in Mark's example), g wouldn't pass it on to f. By forcing >>> the reconstruction of the map from explicit args, you're forced to use the >>> value (incorrectly) destructured in g. Mark could work around it in his >>> example by using (apply f (mapcat identity m)) in g, but it's far from >>> intuitive. >>> >>> >>> On 1 May 2014 15:04, Jim Crossley <j...@crossleys.org> wrote: >>> >>>> Unless I'm missing something subtle, all of your points would hold if >>>> you removed the & in your argument vector to turn your kwargs into an >>>> explicit map, wouldn't they? One advantage is you'd be able to (apply f >>>> [m]), but I'm not sure the :or logic would be any less troublesome. >>>> >>>> >>>> On Wed, Apr 30, 2014 at 8:06 PM, Mark Engelberg <mark.en...@gmail.com> >>>> wrote: >>>> >>>>> Here's the thing I can't stand about keyword args: >>>>> >>>>> Let's start off with a simple function that looks for keys x and y, >>>>> and if either is missing, >>>>> replaces the value with 1 or 2 respectively. >>>>> >>>>> (defn f [& {:keys [x y] :or {x 1 y 2}}] >>>>> [x y]) >>>>> >>>>> => (f :x 10) >>>>> [10 2] >>>>> >>>>> So far, so good. >>>>> >>>>> Now, let's do an extremely simple test of composability. Let's define >>>>> a function g that destructures the keyword args, and if a certain keyword >>>>> :call-f is set, then we're just going to turn around and call f, passing >>>>> all the keyword args along to f. >>>>> >>>>> (defn g [& {call-f :call-f :as m}] >>>>> (when call-f >>>>> (apply f m))) >>>>> >>>>> => (g :call-f true :x 10) >>>>> [1 2] >>>>> >>>>> What? Oh right, you can't apply the function f to the map m. This >>>>> doesn't work. If we want to "apply" f, we somehow need to apply it to a >>>>> sequence of alternating keys and values, not a map. >>>>> >>>>> Take 2: >>>>> >>>>> (defn g [& {:keys [call-f x y] :as m}] >>>>> (when call-f >>>>> (f :x x :y y))) >>>>> >>>>> OK, so this time we try to workaround things by explicitly calling out >>>>> the names of all the keywords we want to capture and pass along. It's >>>>> ugly, and doesn't seem to scale well to situations where you have an >>>>> unknown but at first glance, it seems to work: >>>>> >>>>> => (g :call-f true :x 80 :y 20) >>>>> [80 20] >>>>> >>>>> Or does it? >>>>> >>>>> => (g :call-f true :x 10) >>>>> [10 nil] >>>>> >>>>> What is going on here? Why is the answer coming out that :y is nil, >>>>> when function f explicitly uses :or to have :y default to 2? >>>>> >>>>> The answer is that :or doesn't do what you think it does. The word >>>>> "or" implies that it substitutes the default value of :y any time the >>>>> destructured :y is nil or false. But that's not how it really works. It >>>>> doesn't destructure and then test against nil; instead the :or map only >>>>> kicks in when :y is actually missing as a key of the map. >>>>> >>>>> This means that in g, when we actively destructured :y, it got set to >>>>> a nil, and then that got passed along to f. f's :or map didn't kick in >>>>> because :y was set to nil, not absent. >>>>> >>>>> This is awful. You can't pass through keyword arguments to other >>>>> functions without explicitly destructuring them, and if you destructure >>>>> them and pass them along explicitly, nil values aren't picked up as >>>>> absent >>>>> values, so the :or default maps don't work properly. >>>>> >>>>> To put it simply, keyword args are bad news for composability. >>>>> >>>>> It's a shame, and I'd love to see this improved (rather than just >>>>> having the community give up on keyword arguments). >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To post to this group, send email to clo...@googlegroups.com >>>>> Note that posts from new members are moderated - please be patient >>>>> with your first post. >>>>> To unsubscribe from this group, send email to >>>>> clojure+u...@googlegroups.com >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/clojure?hl=en >>>>> --- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to clojure+u...@googlegroups.com. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clo...@googlegroups.com >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> clojure+u...@googlegroups.com >>>> For more options, visit this group at >>>> http://groups.google.com/group/clojure?hl=en >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to clojure+u...@googlegroups.com. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clo...@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+u...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+u...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.