Forms and evaluation
The text of a program is a sequence of forms. A form is evaluated by what it is:
- A symbol is a variable (or a symbol macro, which expands into another form). Keywords,
t,niland the constants evaluate to themselves. - A list whose first element is a symbol names an operator. If it is one of the 25 special operators, the compiler knows how to evaluate it. If it names a macro, the form is first expanded by calling the macro function on the unevaluated form, and the expansion is evaluated. Otherwise it is a function call: the arguments are evaluated left to right and passed to the function.
- A list whose first element is a lambda expression
((lambda (x) …) arg)is a call of an anonymous function. - Any other object (numbers, strings, characters, vectors, arrays) is self-evaluating.
A name can be a function and a variable at the same time, and a macro and a special operator cannot share a name. An implementation may implement a special operator as a macro, and may implement a standard macro as a special operator if it also supplies an equivalent macro definition, so portable programs do not rely on which is which. special-operator-p tests a symbol; macro-function and fdefinition look up the others.
The 25 special operators
| Operator | Syntax | What it does |
|---|---|---|
block | (block name form*) | Opens a lexically scoped, named exit point. nil blocks are made by do, dolist, loop and others. |
return-from | (return-from name [result]) | Leaves the block named name with the value of result. |
catch | (catch tag form*) | Opens a dynamically scoped exit point, found by tag with eq. |
throw | (throw tag result) | Transfers to the innermost active catch with that tag. |
eval-when | (eval-when (situation*) form*) | Says when its body is evaluated: :compile-toplevel, :load-toplevel, :execute. The old names compile, load, eval are deprecated. |
flet | (flet ((name lambda-list form*)*) form*) | Local functions that cannot call themselves by name. |
labels | (labels ((name lambda-list form*)*) form*) | Local functions that can call themselves and each other (recursion). |
macrolet | (macrolet ((name lambda-list form*)*) form*) | Local macros, expanded at compile time. |
symbol-macrolet | (symbol-macrolet ((name expansion)*) form*) | Local symbol macros: name stands for the expansion form. |
function | (function name-or-lambda) | The function object. Written #'name; for a local or global function and for (lambda …) and (setf name). |
go | (go tag) | Transfers control to a tag in the lexically enclosing tagbody. |
tagbody | (tagbody {tag | statement}*) | A body in which atoms (symbols or integers) are tags and lists are statements; returns nil. The base of prog, do and loop. |
if | (if test then [else]) | The conditional; the else form is nil if omitted. |
let | (let ((var [init])*) declaration* form*) | Binds variables in parallel, lexically (or dynamically, for special variables). |
let* | (let* ((var [init])*) declaration* form*) | Binds variables in sequence, each init seeing the earlier ones. |
load-time-value | (load-time-value form [read-only-p]) | Evaluates form once, when the code is loaded, and the value is a constant in the code. |
locally | (locally declaration* form*) | Evaluates the forms with local declarations, without binding. |
multiple-value-call | (multiple-value-call function form*) | Calls the function with all the values of every form as arguments. |
multiple-value-prog1 | (multiple-value-prog1 first form*) | Evaluates all; returns all the values of the first. |
progn | (progn form*) | Evaluates in order; returns the values of the last. Keeps its body at top level. |
progv | (progv symbols values form*) | Binds dynamic variables whose names are computed at run time. |
quote | (quote object) | Returns object unevaluated. Written 'object. |
setq | (setq {var form}*) | Assigns to variables, in sequence (psetq does it in parallel). Also assigns to symbol macros. |
the | (the value-type form) | Declares the type of the values of form; a promise, not a conversion. |
unwind-protect | (unwind-protect protected cleanup*) | Evaluates protected and then always the cleanup forms, even if control leaves by return-from, go, throw or an error. |
The word declare is not a special operator and not a macro: it is part of the syntax of the forms that allow declarations (let, defun, lambda and others), and a declare evaluated as a form is an error. The viewer colours it with the special operators. The macros that most programs use instead of the special operators are on Standard macros.
(defun find-first (pred tree)
(block search
(labels ((walk (x)
(cond ((funcall pred x) (return-from search x))
((consp x) (walk (car x)) (walk (cdr x))))))
(walk tree)
nil)))
block, labels and return-from give an early exit from a recursive walk.Lambda lists
A lambda list names the parameters of a function or macro. In the ordinary lambda list of defun and lambda, the parts come in this order, each optional.
| Part | Meaning |
|---|---|
var* | required parameters |
&optional {var | (var [init [supplied-p]])}* | optional parameters, with a default form and a variable that tells whether the caller gave the argument |
&rest var | the remaining arguments as a list (&body means the same in a macro, and tells editors to indent the rest as a body) |
&key {var | ((keyword var) [init [supplied-p]])}* | keyword parameters: (f :x 1); the keyword is a keyword made from the variable name unless given |
&allow-other-keys | accept keywords that are not listed (a caller can also pass :allow-other-keys t) |
&aux {var | (var [init])}* | local variables, bound like let* |
The other kinds add to this. A macro lambda list (defmacro, macrolet, define-compiler-macro) can destructure its parameters with nested lists, take a dotted tail, and has &whole var (first, the whole form) and &environment var (the lexical environment, for macroexpand). A destructuring lambda list (destructuring-bind, and macros) accepts &whole but not &environment. A specialised lambda list (defmethod) writes required parameters as (var specialiser) where the specialiser is a class name, (eql object), or t. A generic function lambda list (defgeneric) has no defaults or supplied-p variables. The others are the boa lambda list of defstruct constructors, the defsetf, deftype, define-modify-macro and define-method-combination lists, which are variations on the same keywords. lambda-list-keywords holds the list for the implementation, and lambda-parameters-limit, call-arguments-limit and multiple-values-limit are the limits.
The eight standard lambda-list keywords are &allow-other-keys, &aux, &body, &environment, &key, &optional, &rest and &whole. The viewer colours them wherever they appear, because they are part of how lists such as (&optional x) in a quote or a macro template read.
(defun connect (host &optional (port 80) &key (timeout 30 timeout-p) &allow-other-keys)
(list host port timeout timeout-p))
(defmacro with-timing ((var) &body body)
`(let ((,var (get-internal-real-time)))
,@body))