parent-type—a symbol naming a condition type.
If no parent-types are supplied,
the parent-types default to
default-initargs—a list of keyword/value pairs.
Slot-spec—the name of a slot or a list consisting of the slot-name followed by zero or more slot-options.
Slot-name—a slot name (a symbol), the list of a slot name, or the list of slot name/slot form pairs.
Option—Any of the following:
:reader can be supplied more than once for a given slot
and cannot be
:writer can be supplied more than once for a given slot
and must name a generic function.
:accessor can be supplied more than once for a given slot
and cannot be
:allocation can be supplied once at most for a given slot.
The default if :allocation is not supplied is :instance.
:initarg can be supplied more than once for a given slot.
:initform can be supplied once at most for a given slot.
:type can be supplied once at most for a given slot.
:documentation can be supplied once at most for a given slot.
:report can be supplied once at most.
define-condition defines a new condition type called name,
which is a subtype of
the type or types named by
Each parent-type argument specifies a direct supertype
of the new condition. The new condition
inherits slots and methods from each of its direct
supertypes, and so on.
If a slot name/slot form pair is supplied,
the slot form is a form that
can be evaluated by
produce a default value when an explicit value is not provided. If no
is supplied, the contents of the slot
is initialized in an
If the type being defined and some other type from which it inherits have a slot by the same name, only one slot is allocated in the condition, but the supplied slot form overrides any slot form that might otherwise have been inherited from a parent-type. If no slot form is supplied, the inherited slot form (if any) is still visible.
Accessors are created according to the same rules as used by
A description of slot-options follows:
The :reader slot option specifies that an unqualified method is
to be defined on the generic function named by the argument
to :reader to read the value of the given slot.
define-conditionform was evaluated. Note that the lexical environment refers both to variables and to functions. For local slots, the dynamic environment is the dynamic environment in which
make-conditionwas called; for shared slots, the dynamic environment is the dynamic environment in which the
define-conditionform was evaluated.
No implementation is permitted to extend the syntax of
) as an abbreviation for
The :initarg slot option declares an initialization
argument named by its symbol argument
and specifies that this
initialization argument initializes the given slot. If the
initialization argument has a value in the call to
initialize-instance, the value is stored into the given slot,
and the slot's :initform slot option, if any, is not
evaluated. If none of the initialization arguments specified for a
given slot has a value, the slot is initialized according to the
:initform slot option, if specified.
The :type slot option specifies that the contents of the
slot is always of the specified type. It effectively
declares the result type of the reader generic function when applied
to an object of this condition type.
The consequences of attempting to store in a
slot a value that
does not satisfy the type of the slot is undefined.
This option is treated the same as it would be
The :documentation slot option provides a documentation string
for the slot.
Condition reporting is mediated through the
method for the condition type in question, with
in the definition of a condition type
C is equivalent to:
(defmethod print-object ((x c) stream) (if *print-escape* (call-next-method) (report-name x stream)))
If the value supplied by the argument to :report (report-name)
is a symbol or a lambda expression,
it must be acceptable to
in the current lexical environment.
It should return a function
arguments, a condition and a stream,
that prints on the stream a
description of the condition.
This function is called whenever the
condition is printed while
If report-name is a string, it is a shorthand for
(lambda (condition stream) (declare (ignore condition)) (write-string report-name stream))
This option is processed after the new condition type has been defined, so use of the slot accessors within the :report function is permitted. If this option is not supplied, information about how to report this type of condition is inherited from the parent-type.
The consequences are unspecifed if an attempt is made to read a slot that has not been explicitly initialized and that has not been given a default value.
The consequences are unspecified if an attempt is made to assign the
slots by using
define-condition form appears as a top level form,
the compiler must make name recognizable as a valid type name,
and it must be possible to reference the condition type as the
parent-type of another condition type in a subsequent
define-condition form in the file being compiled.
The following form defines a condition of type
peg/hole-mismatch which inherits from a condition type
(define-condition peg/hole-mismatch (blocks-world-error) ((peg-shape :initarg :peg-shape :reader peg/hole-mismatch-peg-shape) (hole-shape :initarg :hole-shape :reader peg/hole-mismatch-hole-shape)) (:report (lambda (condition stream) (format stream "A ~A peg cannot go in a ~A hole." (peg/hole-mismatch-peg-shape condition) (peg/hole-mismatch-hole-shape condition)))))
The new type has slots
apply to objects of this type, as illustrated in the :report information.
The following form defines a condition type named
which inherits from
(define-condition machine-error (error) ((machine-name :initarg :machine-name :reader machine-error-machine-name)) (:report (lambda (condition stream) (format stream "There is a problem with ~A." (machine-error-machine-name condition)))))
Building on this definition, a new error condition can be defined which
is a subtype of
machine-error for use when machines are not available:
(define-condition machine-not-available-error (machine-error) () (:report (lambda (condition stream) (format stream "The machine ~A is not available." (machine-error-machine-name condition)))))
This defines a still more specific condition, built upon
machine-not-available-error, which provides a slot initialization form
machine-name but which does not provide any new slots or report
information. It just gives the
machine-name slot a default initialization:
(define-condition my-favorite-machine-not-available-error (machine-not-available-error) ((machine-name :initform "mc.lcs.mit.edu")))
Note that since no :report clause was given, the information
machine-not-available-error is used to
report this type of condition.
(define-condition ate-too-much (error) ((person :initarg :person :reader ate-too-much-person) (weight :initarg :weight :reader ate-too-much-weight) (kind-of-food :initarg :kind-of-food :reader :ate-too-much-kind-of-food))) → ATE-TOO-MUCH (define-condition ate-too-much-ice-cream (ate-too-much) ((kind-of-food :initform 'ice-cream) (flavor :initarg :flavor :reader ate-too-much-ice-cream-flavor :initform 'vanilla )) (:report (lambda (condition stream) (format stream "~A ate too much ~A ice-cream" (ate-too-much-person condition) (ate-too-much-ice-cream-flavor condition))))) → ATE-TOO-MUCH-ICE-CREAM (make-condition 'ate-too-much-ice-cream :person 'fred :weight 300 :flavor 'chocolate) → #<ATE-TOO-MUCH-ICE-CREAM 32236101> (format t "~A" *) ▷ FRED ate too much CHOCOLATE ice-cream → NIL
make-condition, defclass, Section 9.1 (Condition System Concepts)