Common Lisp the Language, 2nd Edition
These facilities are designed to make it convenient for the user to insert error checks into code.
[Macro]
check-type place typespec [string]
check-type signals an error if the contents of place are not
of the desired type.
Upon continuing from this error, the user will be asked for a new value;
check-type will store the new value in place and start over,
checking the type of the new value and signaling
another error if it is still not of the desired type. Subforms of
place may be evaluated multiple times because of the implicit
loop generated. check-type returns nil.
The place must be a generalized variable reference acceptable to setf. The typespec must be a type specifier; it is not evaluated. The string should be an English description of the type, starting with an indefinite article (``a'' or ``an''); it is evaluated. If string is not supplied, it is computed automatically from typespec. (The optional string argument is allowed because some applications of check-type may require a more specific description of what is wanted than can be generated automatically from the type specifier.)
The error message will mention place, its contents, and the desired type.
The precise format and content of the error message
is implementation-dependent. The example shown below
is representative of current practice.
X3J13 voted in June 1988
(CONDITION-SYSTEM)
to adopt a proposal for a Common Lisp Condition System.
This proposal modifies the definition of check-type to specify its
interaction with the condition system. See section 29.4.2.
X3J13 voted in March 1988 (PUSH-EVALUATION-ORDER)
to clarify order of evaluation (see section 7.2).
Examples:
(setq aardvarks '(sam harry fred)) (check-type aardvarks (vector integer)) Error: The value of AARDVARKS, (SAM HARRY FRED), is not a vector of integers. (setq naards 'foo) (check-type naards (integer 0 *) "a positive integer") Error: The value of NAARDS, FOO, is not a positive integer.
[Macro]
assert test-form [({place}*) [string {arg}*]]
assert signals an error if the value of test-form is nil.
Continuing
from this error will allow the user to alter the values of some
variables, and assert will then start over, evaluating
test-form again. assert returns nil.
test-form is any form. Each place (there may be any number of them, or none) must be a generalized-variable reference acceptable to setf. These should be variables on which test-form depends, whose values may sensibly be changed by the user in attempting to correct the error. Subforms of each place are only evaluated if an error is signaled, and may be re-evaluated if the error is re-signaled (after continuing without actually fixing the problem).
The string is an
error message string, and the args are additional arguments; they are
evaluated only if an error is signaled, and re-evaluated if the error is
signaled again.
The function format is applied in the usual way to
string and args to produce
the actual error message. If string is omitted (and therefore also
the args), a default error message is used.
X3J13 voted in June 1988
(CONDITION-SYSTEM)
to adopt a proposal for a Common Lisp Condition System.
This proposal modifies the definition of assert to specify its
interaction with the condition system. See section 29.4.2.
X3J13 voted in March 1988 (PUSH-EVALUATION-ORDER) to clarify order of evaluation (see section 7.2).
X3J13 voted in June 1989 (SETF-MULTIPLE-STORE-VARIABLES)
to extend the specification of assert to allow a place
whose setf method has more than one store variable (see define-setf-method).
Examples:
(assert (valve-closed-p v1)) (assert (valve-closed-p v1) () "Live steam is escaping!") (assert (valve-closed-p v1) ((valve-manual-control v1)) "Live steam is escaping!") ;; Note here that the user is invited to change BASE, ;; but not the bounds MINBASE and MAXBASE. (assert (<= minbase base maxbase) (base) "Base ~D is not in the range ~D, ~D" base minbase maxbase) ;; Note here that it is probably not desirable to include the ;; entire contents of the two matrices in the error message. ;; It is reasonable to assume that the debugger will give ;; the user access to the values of the places A and B. (assert (= (array-dimension a 1) (array-dimension b 0)) (a b) "Cannot multiply a ~D-by-~D matrix ~ and a ~D-by-~D matrix." (array-dimension a 0) (array-dimension a 1) (array-dimension b 0) (array-dimension b 1))