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 > <javascript:>> 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 <javascript:>> >> 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 >>> <javascript:>> 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 >>>> <javascript:> >>>> 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 <javascript:> >>>> 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 <javascript:>. >>>> 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 >>> <javascript:> >>> 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 <javascript:> >>> 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 <javascript:>. >>> 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 >> <javascript:> >> 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 <javascript:> >> 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 <javascript:>. >> 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.