Common Lisp constructs are described not only in terms of their behavior in situations during which they are intended to be used (see the “Description” part of each operator specification), but in all other situations (see the “Exceptional Situations” part of each operator specification).
A situation is the evaluation of an expression in a specific context.
A condition is an object that
represents a specific situation that has been detected.
Conditions are generalized instances of the class
A hierarchy of condition classes is defined in Common Lisp.
A condition has slots that contain data
relevant to the situation that the condition represents.
An error is a situation in which normal program execution cannot continue correctly without some form of intervention (either interactively by the user or under program control). Not all errors are detected. When an error goes undetected, the effects can be implementation-dependent, implementation-defined, unspecified, or undefined. See Section 1.4 (Definitions). All detected errors can be represented by conditions, but not all conditions represent errors.
Signaling is the process by which a condition can alter
the flow of control in a program by raising the
condition which can then be handled. The functions
warn are used to signal conditions.
The process of signaling involves the selection and invocation of a handler from a set of active handlers. A handler is a function of one argument (the condition) that is invoked to handle a condition. Each handler is associated with a condition type, and a handler will be invoked only on a condition of the handler's associated type.
Active handlers are established dynamically
Handlers are invoked in a dynamic environment
equivalent to that of the signaler,
except that the set of active handlers
is bound in such a way as to include only those that were active
at the time the handler being invoked was established.
Signaling a condition has no side-effect on the condition,
and there is no dynamic state contained in a condition.
If a handler is invoked, it can address the situation in one of three ways:
It can decline to handle the condition. It does this by
simply returning rather than transferring control.
When this happens, any values returned by the handler are
ignored and the next most recently established handler is invoked.
If there is no such handler and the signaling function is
cerror, the debugger is entered in the
dynamic environment of the signaler. If there is no such
handler and the signaling function is either
warn, the signaling function simply returns
It can handle the condition by performing a non-local
transfer of control. This can be done either primitively by using
throw or more
abstractly by using a function such as
It can put off a decision about whether to handle or decline, by any of a number of actions, but most commonly by signaling another condition, resignaling the same condition, or forcing entry into the debugger.