params ⇒ positional-param* , or positional-param* & rest-param
positional-param ⇒ binding-form
rest-param ⇒ binding-form
name ⇒ symbol
Defines a function (fn). Fns are first-class objects that implement the IFn interface. The IFn
interface defines an invoke()
function that is overloaded with arity ranging from 0-20. A single fn object can implement one or more invoke methods, and thus be overloaded on arity. One and only one overload can itself be variadic, by specifying the ampersand followed by a single rest-param. Such a variadic entry point, when called with arguments that exceed the positional params, will find them in a seq contained in the rest param. If the supplied args do not exceed the positional params, the rest param will be nil.
The first form defines a fn with a single invoke method. The second defines a fn with one or more overloaded invoke methods. The arities of the overloads must be distinct. In either case, the result of the expression is a single fn object.
The expressions exprs are compiled in an environment in which the params are bound to the actual arguments. The exprs are enclosed in an implicit do
. If a name symbol is provided, it is bound within the function definition to the function object itself, allowing for self-calling, even in anonymous functions. If a param symbol is annotated with a metadata tag, the compiler will try to resolve the tag to a class name and presume that type in subsequent references to the binding.
(def mult
(fn this
([] 1)
([x] x)
([x y] (* x y))
([x y & more]
(apply this (this x y) more))))
Note that named fns such as mult
are normally defined with defn
, which expands into something such as the above.
A fn (overload) defines a recursion point at the top of the function, with arity equal to the number of params including the rest param, if present. See recur
.
fns implement the Java Callable
, Runnable
and Comparator
interfaces.
Functions support specifying runtime pre- and post-conditions.
The syntax for function definitions becomes the following: