Dave Tenny <dave.te...@gmail.com> 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 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.

Reply via email to