When I do the following it works:
user> (#(+ % 8) 7)
15
But why doesn't this work?
user> (#({:a %}) 7)
Execution error (ArityException) at user/eval74597$fn (form-init937950372947324749.clj:760).
Wrong number of args (0) passed to: clojure.lang.PersistentArrayMap
Expected result: {:a 7}
Anon-fn with #() are a reader macro. If you look at the code generated, it becomes obvious, why it does not work (the body is called):
user=> '#({:a %})
(fn* [p1__8266#] ({:a p1__8266#}))
So the arg is passed as key for one map and it's called at once, since that is what the reader macro does. The usually safe way around this is using do, when you want to use the data literals:
user=> (#(do {:a %}) 7)
{:a 7}
Or, of course, using the various functions like hash-map to create the data structure.
This is because the way the anonymous function shorthand expands, which on a clojure.lang.PersistentArrayMap happens to be invalid.
The #(+ % 8) shorthand is a macro that expands to:
(fn* [x] (+ x 8))
When you call it with #({:a %}) it expands to:
(fn* [x] ({:a x}))
Which tries to invoke the map as a function without its required arguments. Alternatively you can use assoc to achieve the desired result:
user=> (#(assoc {} :a %) 7)
{:a 7}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With