11

I am just learning the language and I've got a simple question. Why does this work (constructs {:key "value"}):

(#(assoc {} :key %) "value")

But this doesn't:

(#({:key %}) "value")
ArityException Wrong number of args (0) passed to: PersistentArrayMap  clojure.lang.AFn.throwArity (AFn.java:429)

On Python the latter syntax is perfectly valid:

> (lambda v: {'key': v})('value')
{'key': 'value'}

edit: thanks for great answers, it is apparent I need to stop thinking # as equivalent to lambda in Python.

3
  • 1
    #(f x) == (fn [] (f x)) :. #({x}) == (fn [] ({x})) Commented Jun 9, 2016 at 20:34
  • 2
    It's a littly hacky but if you want to return an element from an anon fn: #(-> {:key %}) Commented Jun 10, 2016 at 5:28
  • 1
    also #(hash-map :k %) Commented Jun 10, 2016 at 6:19

3 Answers 3

14

#(f %) is expanded by the reader into (fn [%] (f %). Likewise, #({:key %}) is expanded into (fn [%] ({:key %}). The python equivalent of this would be lambda v: {'key': v}(), which has the exact same problem as the Clojure version.

What you are looking for is something equivalent to (fn [v] {:key v}). If you really want to use #(...) notation, you could use #(do {:key %}).

Incidentally, I personally never use #(...). I think it's more difficult to grok (as examples such as this evidence), and is only very slightly more compact than an equivalent fn form. Then there's also the limitation that #(...) forms can not be nested.

Sign up to request clarification or add additional context in comments.

Comments

5

That is the limitation of #() reader. fn will work fine.

user=> ((fn [x] {:key x}) "value")
{:key "value"}

Please take a look at the document Anonymous function literal (#())

2 Comments

What limitation are you referring to? The only limitation I see from the link you posted is that "#() forms cannot be nested." But that doesn't apply in this situation....
According to the document, #(…​) will be translated to (fn [args] (…​)). So #({:key %}) will be translated to (fn [x] ({:key x})). This will cause error because {:key x} is in function position and doesn't make sense.
0

{:key %} is a PersistentArrayMap. You have it in the "verb position" in your function call. You need a Clojure method of some type in there to avoid that error, as you can see in your first (working) example.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.