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 <[email protected]
> <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 <[email protected] <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 <[email protected]
>>> <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 [email protected]
>>>> <javascript:>
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> [email protected] <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 [email protected] <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 [email protected]
>>> <javascript:>
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> [email protected] <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 [email protected] <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 [email protected]
>> <javascript:>
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> [email protected] <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 [email protected] <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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.