Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Clojure: Anonymous Functions Using Short Notation

DZone's Guide to

Clojure: Anonymous Functions Using Short Notation

· Java Zone
Free Resource

The single app analytics solutions to take your web and mobile apps to the next level.  Try today!  Brought to you in partnership with CA Technologies

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 [1 2 arg] 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 identity function is one such function:

> (#(identity [1 2 %]) 6)
[1 2 6]

Or if we want to be more concise the thread-first (->) works too:

> (#(-> [1 2 %]) 6)
[1 2 6]

CA App Experience Analytics, a whole new level of visibility. Learn more. Brought to you in partnership with CA Technologies.

Topics:

Published at DZone with permission of Mark Needham, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}