On this page:

3.1 Declarations


(def name value)

Defines a new variable of name with the given value.


(def fn name args body ...+)

args = (arg ...)
  | (arg ... . rest-id)
  | args-id
arg = arg-id
  | [arg-id default-expr]
Defines a function of name, which when called evaluates its body expressions with the given list of arguments bound to local variables for use in the body of the function’s definition. Note that there are a number of additional options here for defining arguments. Default values can be ascribed to an argument by enclosing it in additional parentheses:

> (def fn foo (x (y 1)) (+ x y))
> (foo 3 4)


> (foo 5)


Two patterns as well exist for taking an arbitrary number of values. The argument names list can be forgone entirely and substituted with a single name (generally args* by convention), which will then contain a list of any and all values passed to the function. The second method is the use of the dot (.) in the body of the arguments list followed by a single variable (usually called rest).

> (def fn foo args* args*)
> (foo)


> (foo 3 4 5)

'(3 4 5)

> (def fn bar (x y . rest) (join (+ x y) rest))
> (bar 3 4)


> (bar 3 4 5 6 7 8)

'(7 5 6 7 8)


(def macro name (pattern ...) template)

Defines a new macro with name. A macro can best be thought of as a function which is not evaluated, but rather returns syntax to be evaluated in the form of a template. Each name described in the pattern defines a "pattern variable" which can then be used in the body of the template and will pass any syntax contained in that portion of the pattern in the appropriate location matched in the template. The elipsis ... can be used in a pattern to indicate repeatable values.


(def macroset name [(name pattern ...) template] ...)

(def macroset name (literal ...) [(name pattern ...) template] ...)
Similar to def macro, except that multiple matching patterns can be defined allowing for macros with variable syntax. Like def macro, the ... symbol can be used to indicate repeating values.


(let ((name value) ...) body ...+)

Binds the given name-value pairs for use in the local context created by the body of the expression. This is used to define local variables, such as are needed within a function. Note that local functions can potentially be assigned this way by storing anonymous functions, but there is a built-in syntax for defining a single such function, like so:


(let proc-id ((name value) ...) body ...)

When let is called this way, it defines a local function proc (conventionally called recur), which can then be called from within the body of the let in order to perform local recursion; the name-value pairs thus act as arguments to the function proc.


(fn (arg ...) body ...)

Creates an anonymous function with the given arguments, that evaluates its body when called. This is the lambda expression from other Lisps and functional languages, and a given fn can be passed as a value (as can named functions, for that matter) wherever called for. An anonymous function can also be evaluated directly in place by using it as the operator in an expression, like so:

> ((fn (x y) (* x y)) 4 5)