194 lines
9.3 KiB
HTML
194 lines
9.3 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
|
|
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
|
|
<HEAD>
|
|
<TITLE>29.4.2. Assertions</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
<meta name="description" value=" Assertions">
|
|
<meta name="keywords" value="clm">
|
|
<meta name="resource-type" value="document">
|
|
<meta name="distribution" value="global">
|
|
<P>
|
|
<b>Common Lisp the Language, 2nd Edition</b>
|
|
<BR> <HR><A NAME=tex2html5896 HREF="node337.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html5894 HREF="node334.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html5888 HREF="node335.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html5898 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html5899 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
|
<B> Next:</B> <A NAME=tex2html5897 HREF="node337.html"> Exhaustive Case Analysis</A>
|
|
<B>Up:</B> <A NAME=tex2html5895 HREF="node334.html"> Program Interface to </A>
|
|
<B> Previous:</B> <A NAME=tex2html5889 HREF="node335.html"> Signaling Conditions</A>
|
|
<HR> <P>
|
|
<H2><A NAME=SECTION003342000000000000000>29.4.2. Assertions</A></H2>
|
|
<P>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
|
|
<A NAME=CONDITIONASSERTIONS>These</A>
|
|
facilities are designed to make it convenient for the user
|
|
to insert error checks into code.
|
|
<P>
|
|
<BR><b>[Macro]</b><BR>
|
|
<tt>check-type <i>place</i> <i>typespec</i> [<i>string</i>]</tt><P> [This supersedes the description of <tt>check-type</tt>
|
|
given in section <A HREF="node221.html#SPECIALIZEDERRORSIGNALLING">24.2</A>.-GLS]
|
|
<P>
|
|
A <tt>check-type</tt> form signals an error of type
|
|
<tt>type-error</tt> if the contents of <i>place</i> are not of the
|
|
desired type.
|
|
<P>
|
|
If a condition is signaled, handlers of this condition can use the
|
|
functions <tt>type-error-datum</tt> and <tt>type-error-expected-type</tt> to access the
|
|
contents of <i>place</i> and the <i>typespec</i>, respectively.
|
|
<P>
|
|
This function can return only if the <tt>store-value</tt> restart is invoked, either
|
|
explicitly from a handler or implicitly as one of the options offered by the
|
|
debugger.
|
|
The restart is associated with the signaled condition as if by
|
|
use of <tt>with-condition-restarts</tt>.
|
|
<P>
|
|
If <tt>store-value</tt> is called, <tt>check-type</tt> will store the new value that is
|
|
the argument to <tt>store-value</tt> (or that is prompted for interactively by
|
|
the debugger) in <i>place</i> and start over, checking the type of the new value
|
|
and signaling another error if it is still not the desired type. Subforms
|
|
of <i>place</i> may be evaluated multiple times because of the implicit loop
|
|
generated. <tt>check-type</tt> returns <tt>nil</tt>.
|
|
<P>
|
|
The <i>place</i> must be a generalized variable reference acceptable to <tt>setf</tt>. The
|
|
<i>typespec</i> must be a type specifier; it is not evaluated. The <tt>string</tt> should
|
|
be an English description of the type, starting with an indefinite article
|
|
(``a'' or ``an''); it is evaluated. If the <i>string</i> is not supplied, it is computed
|
|
automatically from the <i>typespec</i>. (The optional <i>string</i> argument is allowed
|
|
because some applications of <tt>check-type</tt> may require a more specific
|
|
description of what is wanted than can be generated automatically from the
|
|
type specifier.)
|
|
<P>
|
|
The error message will mention the <i>place</i>, its contents, and the desired type.
|
|
<P>
|
|
<hr>
|
|
<b>Implementation note:</b> An implementation may choose to generate a somewhat
|
|
differently worded error message if it recognizes that <i>place</i> is of a
|
|
particular form, such as one of the arguments to the function that called
|
|
<tt>check-type</tt>.
|
|
<hr>
|
|
<P>
|
|
<P><pre>
|
|
Lisp> (setq aardvarks '(sam harry fred))
|
|
=> (SAM HARRY FRED)
|
|
Lisp> (check-type aardvarks (array * (3)))
|
|
Error: The value of AARDVARKS, (SAM HARRY FRED),
|
|
is not a 3-long array.
|
|
To continue, type :CONTINUE followed by an option number:
|
|
1: Specify a value to use instead.
|
|
2: Return to Lisp Toplevel.
|
|
Debug> :continue 1
|
|
Use Value: #(sam fred harry)
|
|
=> NIL
|
|
Lisp> aardvarks
|
|
=> #<ARRAY-3 13571>
|
|
Lisp> (map 'list #'identity aardvarks)
|
|
=> (SAM FRED HARRY)
|
|
Lisp> (setq aacount 'foo)
|
|
=> FOO
|
|
Lisp> (check-type aacount (integer 0 *) "a non-negative integer")
|
|
Error: The value of AACOUNT, FOO, is not a non-negative integer.
|
|
To continue, type :CONTINUE followed by an option number:
|
|
1: Specify a value to use instead.
|
|
2: Return to Lisp Toplevel.
|
|
Debug> :continue 2
|
|
Lisp>
|
|
</pre><P>
|
|
<P>
|
|
<hr>
|
|
<b>Compatibility note:</b> In Zetalisp, the equivalent facility is called <tt>check-arg-type</tt>.
|
|
<hr>
|
|
<P>
|
|
<BR><b>[Macro]</b><BR>
|
|
<tt>assert <i>test-form</i> [({<i>place</i>}*) [<i>datum</i> {<i>argument</i>}*]]</tt><P> [This supersedes the description of <tt>assert</tt>
|
|
given in section <A HREF="node221.html#SPECIALIZEDERRORSIGNALLING">24.2</A>.-GLS]
|
|
<P>
|
|
An <tt>assert</tt> form signals an error if the value of the <i>test-form</i> is <tt>nil</tt>.
|
|
Continuing from this
|
|
error using the <tt>continue</tt> restart will allow the user to alter the values
|
|
of some variables, and <tt>assert</tt> will then start over, evaluating the <i>test-form</i>
|
|
again.
|
|
(The restart is associated with the signaled condition as if by
|
|
use of <tt>with-condition-restarts</tt>.)
|
|
<tt>assert</tt> returns <tt>nil</tt>.
|
|
<P>
|
|
The <i>test-form</i> may be any form. Each <i>place</i> (there may be any number of them,
|
|
or none) must be a generalized variable reference acceptable to <tt>setf</tt>.
|
|
These should be variables on which <i>test-form</i> depends, whose values
|
|
may sensibly be changed by the user in attempting to correct the error.
|
|
Subforms of each <i>place</i> are evaluated only if an error is signaled, and
|
|
may be re-evaluated if the error is re-signaled (after continuing without
|
|
actually fixing the problem).
|
|
<P>
|
|
The <i>datum</i> and <i>argument</i>s are evaluated only if an error is to be
|
|
signaled, and re-evaluated if the error is to be signaled again.
|
|
<P>
|
|
If <i>datum</i> is a condition, then that condition is used directly.
|
|
In this case, it is an error to specify any <i>argument</i>s.
|
|
<P>
|
|
If <i>datum</i> is a condition type (a class or class name), then the condition used is effectively the result
|
|
of <tt>(apply #'make-condition <i>datum</i> (list argument))</tt>.
|
|
<P>
|
|
If <i>datum</i> is a string, then the condition used is effectively the result of
|
|
<P><pre>
|
|
(make-condition 'simple-error
|
|
:format-string <i>datum</i>
|
|
:format-arguments (list argument))
|
|
</pre><P>
|
|
<P>
|
|
If <i>datum</i> is omitted, then a condition of type <tt>simple-error</tt> is
|
|
constructed using the <i>test-form</i> as data. For example, the following
|
|
might be used:
|
|
<P><pre>
|
|
(make-condition 'simple-error
|
|
:format-string "The assertion ~S failed."
|
|
:format-arguments '(<i>test-form</i>))
|
|
</pre><P>
|
|
Note that the <i>test-form</i> itself, and not its value, is used as the format argument.
|
|
<P>
|
|
<hr>
|
|
<b>Implementation note:</b> The debugger need not include the <i>test-form</i> in
|
|
the error message, and any <i>places</i> should not be included in the message,
|
|
but they should be made available for the user's perusal. If the user
|
|
gives the ``continue'' command, an opportunity should be presented
|
|
to alter the values of any or all of the references. The details of this
|
|
depend on the implementation's style of user interface, of course.
|
|
<hr>
|
|
<P>
|
|
Here is an example of the use of <tt>assert</tt>:
|
|
<P><pre>
|
|
(setq x (make-array '(3 5) :initial-element 3))
|
|
(setq y (make-array '(3 5) :initial-element 7))
|
|
|
|
(defun matrix-multiply (a b)
|
|
(let ((*print-array* nil))
|
|
(assert (and (= (array-rank a) (array-rank b) 2)
|
|
(= (array-dimension a 1)
|
|
(array-dimension b 0)))
|
|
(a b)
|
|
"Cannot multiply ~S by ~S." a b)
|
|
(really-matrix-multiply a b)))
|
|
|
|
(matrix-multiply x y)
|
|
Error: Cannot multiply #<ARRAY-3-5 12345> by #<ARRAY-3-5 12364>.
|
|
To continue, type :CONTINUE followed by an option number:
|
|
1: Specify new values.
|
|
2: Return to Lisp Toplevel.
|
|
Debug> :continue 1
|
|
Value for A: x
|
|
Value for B: (make-array '(5 3) :initial-element 6)
|
|
=> #2A(¯(54 54 54 54 54)
|
|
(54 54 54 54 54)
|
|
(54 54 54 54 54)
|
|
(54 54 54 54 54)
|
|
(54 54 54 54 54))
|
|
</pre><P>
|
|
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<P>
|
|
<BR> <HR><A NAME=tex2html5896 HREF="node337.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html5894 HREF="node334.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html5888 HREF="node335.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html5898 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html5899 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
|
<B> Next:</B> <A NAME=tex2html5897 HREF="node337.html"> Exhaustive Case Analysis</A>
|
|
<B>Up:</B> <A NAME=tex2html5895 HREF="node334.html"> Program Interface to </A>
|
|
<B> Previous:</B> <A NAME=tex2html5889 HREF="node335.html"> Signaling Conditions</A>
|
|
<HR> <P>
|
|
<HR>
|
|
<P><ADDRESS>
|
|
AI.Repository@cs.cmu.edu
|
|
</ADDRESS>
|
|
</BODY>
|