Dave Tenny <[email protected]> writes:
Hi Dave,
> At issue (for me), keyword arguments and maps that bundle them.
>
> user> (defn foo [a b & {:keys [c d]}]
> [a b c d])
> #'user/foo
> user> (defn bar [a b & {:keys [c d] :as options}]
> (println (apply foo a b options)))
> #'user/bar
> user> (bar 1 2)
> [1 2 nil nil]
> nil
> ;; Okay so far
>
> user> (bar 1 2 :c 3)
> IllegalArgumentException No value supplied for key: [:c 3]
> clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)
Yes, because `apply` wants to have a sequable thing as its last
argument. A map is a sequable thing: `(seq my-map)` returns `([key1
val1] [key2 val2] ...)`, i.e., a sequence of tuples of the map's keys
and values. However, your `foo` function doesn't want tuples but just
keys and values. Basically, what you are doing is essentially
(foo a b [:c cval] [:d dval])
where it should be
(foo a b :c cval :d dval)
> So maybe this is all fine, though if there's some standard way of
> doing this using things shipped with clojure please let me know.
Well, emulating keyword args with varargs and map destructuring can
sometimes be nice in order to have a nice convenient API but it doesn't
really compose well. I'd suggest to define `foo` with arguments
[a b {:keys [c d]}
i.e., no varargs. Then `bar` can just call `(foo a b options)`. Or
maybe drop varargs altogether and define `bar` as
(defn bar
([a b] (bar a b {}))
([a b {:keys [c d] :as options}] ...))
> However then 'recur' bucks the trend, which adds to confusion.
>
> user> (defn baz [a b & {:keys [c d] :as options}]
> (if (> a 0)
> (recur (- a 1) b options)
> [a b c d]))
> #'user/baz
> user> (baz 2 3 :c 4)
> [0 3 4 nil]
Indeed. Here I had expected as exception "No value supplied for key:
{:c 4}" because the first recur call should be equivalent to `(baz 1 3
{:c 4})`, and
user> (baz 1 3 {:c 4})
; IllegalArgumentException No value supplied for key: {:c 4}
; clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)
So now I'm also confused. :-)
Bye,
Tassilo
--
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.