Clojure: Anonymous functions using short notation and the 'ArityException Wrong number of args (0) passed to: PersistentVector'
In the time I’ve spent playing around with Clojure one thing I’ve always got confused by is the error message you get when trying to return a vector using the anonymous function shorthand.
For example, if we want function which creates a vector with the values 1, 2, and the argument passed into the function we could write the following:
> ((fn [x] [1 2 x]) 6)
[1 2 6]
However, when I tried to convert it to the shorthand '#()' syntax I got the following exception:
> (#([1 2 %]) 6)
clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector
AFn.java:437 clojure.lang.AFn.throwArity
AFn.java:35 clojure.lang.AFn.invoke
NO_SOURCE_FILE:1 user/eval575[fn]
NO_SOURCE_FILE:1 user/eval575
On previous occasions I’ve just stopped there and gone back to the long hand notation but this time I wanted to figure out why it didn’t work as I expected.
I came across this StackOverflow post which explained the way the shorthand gets expanded:
#() becomes (fn [arg1 arg2] (...))
which means that:
#(([1 2 %]) 6) becomes ((fn [arg] ([1 2 arg])) 6)
We are evaluating the vector as a function but aren’t passing any arguments to it. One way it can be used as a function is if we want to return a value at a specific index e.g.
> ([1 2 6] 2)
6
We don’t want to evaluate a vector as a function, rather we want to return the vector using the shorthand syntax. To do that we need to find a function which will return the argument passed to it and then pass the vector to that function.
The http://clojuredocs.org/clojure_core/clojure.core/identity function is one such function:
> (#(identity [1 2 %]) 6)
[1 2 6]
Or if we want to be more concise the http://clojuredocs.org/clojure_core/clojure.core/-%3E works too:
> (#(-> [1 2 %]) 6)
[1 2 6]
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.