Defines a function.
When a fn
form is evaluated, it allocates and returns a new closure (a value which
belongs to the primitive type fn
). Just like a Rust closure, this closure may capture
any local variables which are in scope. Each local variable may be simultaneously captured
by multiple closures.
(let counter (do
(let n 0)
(fn ()
(inc! n)
n)))
(prn (counter)) ; prints 1
(prn (counter)) ; prints 2
(prn n) ; an error: n is not in scope
If the same fn
form is evaluated multiple times (for example, in a loop), it will
allocate a new closure each time.
params
must be a valid array pattern. When the
function is called, all of its arguments are matched against params
, and then its body
forms are evaluated as an "implicit do". It's an error if the call's arguments do not
match params
- for example, because too few or too many arguments were provided.
(let f (fn (a b c) (prn a b c)))
(f 1 2) ; error: expected 3 or more arguments
The return
or yield
special forms can be used to return early
from the function call. Otherwise, the result of the function call is the evaluation
result of the body
forms.
A fn
form may specify one or more flags, listed immediately before params
:
&name name
specifies the function's name, for debugging purposes.&arg-limits min max
specifies a minimum and maximum argument count. When&arg-limits
is present, theparams
pattern must only contain a single rest param,(..rest)
.min
must be an integer;max
may be an integer or#n
.