How many arguments does an anonymous function expect in clojure?
Asked Answered
B

3

20

How does Clojure determine how many arguments an anonymous function (created with the #... notation) expect?

user=> (#(identity [2]) 14)
java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$eval3745$fn (NO_SOURCE_FILE:0)
Barty answered 20/10, 2011 at 20:9 Comment(0)
E
36

#(println "Hello, world!") -> no arguments

#(println (str "Hello, " % "!")) -> 1 argument (% is a synonym for %1)

#(println (str %1 ", " %2 "!")) -> 2 arguments

and so on. Note that you do not have to use all %ns, the number of arguments expected is defined by the highest n. So #(println (str "Hello, " %2)) still expects two arguments.

You can also use %& to capture rest args as in

(#(println "Hello" (apply str (interpose " and " %&))) "Jim" "John" "Jamey").

From the Clojure docs:

Anonymous function literal (#())
#(...) => (fn [args] (...))
where args are determined by the presence of argument literals taking the 
form %, %n or  %&. % is a synonym for %1, %n designates the nth arg (1-based), 
and %& designates a rest arg. This is not a replacement for fn - idiomatic 
used would be for very short one-off mapping/filter fns and the like. 
#() forms cannot be nested.
Enfeeble answered 20/10, 2011 at 20:32 Comment(1)
What is the points to put extra parenthesis around println in the first 3 code examples?Ire
B
11

It is giving you the error that you passed one argument to your anonymous function that was expecting zero.

The arity of an anonymous function is determined by the highest argument referenced inside.

e.g.

(#(identity [2])) -> arity 0, 0 arguments must be passed

(#(identity [%1]) 14) -> arity 1, 1 argument must be passed

(#(identity [%]) 14) -> (% is an alias for %1 if and only if the arity is 1), 1 argument must be passed

(#(identity [%1 %2]) 14 13) or

(#(identity [%2]) 14 13) -> arity 2, 2 arguments must be passed

(#(identity [%&]) 14) -> arity n, any number of arguments can be passed

Basifixed answered 21/10, 2011 at 14:8 Comment(1)
Cool, neat example with %&. Thanks!Barty
P
5

You need to refer to the arguments with %1, %2 etc. to cause the function to require that many arguments.

Pepperandsalt answered 20/10, 2011 at 20:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.