Learning Clojure/Special Forms

Official documentation on special forms in Clojure: http://clojure.org/special_forms#Special%20Forms

In any Lisp dialect, you need special "primitives", called special forms, which are forms evaluated in a special way. For instance, the rules of Clojure evaluation are missing a way to do conditional evaluation, so we have the special form.

The way arguments to a special form are evaluated is particular to each special form, and these evaluations may change based on context, e.g. the evaluation of special form A may depend on the fact that it is used inside special form B. The Clojure special forms are:

(Arguments to the forms are denoted in italics. Arguments ending ? are optional. Arguments ending * represent 0 or more arguments. Arguments ending + represent 1 or more arguments.)


 * (if test then else?)

If test returns true (any value other than false or nil), then is evaluated and returned. Otherwise, optional else? is evaluated and returned, though if no else? is specified,  is returned.


 * (quote form)

form is returned unevaluated:

This is useful when you wish to, say, pass a symbol as an argument to a regular function:


 * (var symbol)

Normally, a symbol resolving to a Var further evaluates into the value of the Var. The special form  returns the Var itself from a resolved symbol, not the Var's value:

If the symbol does not resolve to a Var, an exception is thrown.


 * (def symbol value)

In the current namespace, symbol is mapped to an interned Var holding value. If a Var mapped to that symbol already exists,  assigns it the new value.

returns the affected Var.

You can  a namespace-qualified symbol, but only if a Var is already interned by that name in that namespace:

Attempting to  to a symbol already mapped to a referred Var throws an exception.


 * (fn name? [params*] body*)

Returns a newly defined function object.

name?: the name of the function seen inside the function; useful for recursive calls.

params*: symbols bound to the local parameters.

body*: args to "evaluate" when the function is called; a function call returns the last value returned in its body.

For example:

Normally, the function object returned by  is preserved in some way, either passed to a function or bound to a Var or some such. In principle, though, you can immediately call the function returned (not that this is a sensible thing to do):

The symbols provided for name? and params* are not resolved but instead establish local names for the function body. Clojure is lexically scoped, so bindings to local variables in a function take precedence over bindings external to the function, e.g. the symbol foo in a function body will resolve to foo in the current namespace only if there is no local foo and no enclosing function with a local named foo.

When a Clojure function is called, its body is not executed by evaluation as you might think, and in fact, the  body is partially evaluated before it returns: symbols are resolved and macros are evaluated so that this work is not done each time the function is called; also, special forms in the body are evaluated as best as logic permits, e.g. a   is evaluated to save from doing the work later, but an   is not evaluated because it represents real work that doesn't make sense to do until the function is actually called. Furthermore, when a function is called, the Clojure evaluator is not really involved because Clojure compiles functions into JVM bytecode. Consider:

When this special form is evaluated, the symbol frog is resolved to a Var in the current namespace. If this Var holds a macro at evaluation time, then the macro call is expanded, but otherwise, the list is compiled into a function call. Assuming frog is not a macro, then when the function we're defining is called and  executed, the function held by the Var of frog is called with the argument 5; if the Var does not refer to a function at that time, an exception is thrown.

(Actually, when the evaluator encounters any function call---whether inside a function body or outside---it always compiles it into bytecode; the difference is that calls outside a function definition are immediately executed by the evaluator after compilation.)

Normally, a function has a fixed arity, i.e. it takes a fixed number of arguments. However, the last parameter of a function can be preceded by & to denote that it takes 0 or more extra arguments as a list:

(Normally,  is just a symbol like any other, but it is treated specially by   for this purpose, so effectively, you can't have a local named  .)

A single function can also be defined with different bodies for different arities using this form:

(fn name? ([params*] body*)+)

For example:

In such a function, only one body can have variable arity, and that body's arity must be greater than any other body's.


 * (do body*)

body is any number of arguments which are evaluated in order; the value of the last argument is returned. (We typically don't use  very frequently because a function body is effectively an implicit   that usually meets our needs.)

where local => name value
 * (let [local*] body*)

Declare a local scope in which one or more locals exist:

The locals defined are immutable and only visible inside the let.

A local name can be used to define another local later in the list:


 * (recur args*)

sends execution back to the last "recursion point", which is usually the immediately enclosing function. Unlike a regular recursive call,  reuses the current stack frame, so it is effectively Clojure's way to do tail-recursion. must be used in "tail position" (i.e. as the very last expression possibly evaluated in the function):

In the future, the JVM may add built-in support for tail-call optimization, at which point  would become unnecessary.


 * (loop [params*] body*)

is just like, except it establishes a "recursion point" for the sake of. Effectively,  is a basic way to do iteration within a function:


 * (throw expr)

Equivalent of Java's.

Just like in Java, a thrown object must be of type java.lang.Throwable or a descendant thereof.


 * (try body* (catch class name body*)* (finally body*)?)

Equivalent of Java's.


 * (monitor-enter)
 * (monitor-exit)

Hickey says, "these are synchronization primitives that should be avoided in user code". You should instead use the macro clojure/locking.


 * (set!)

(Two more special forms,  and   are described in the next section.)