In other languages the compiler does some type checking for you at compile-time. In lisp you have to do checking at runtime (compile time checking can be done also... it mostly turned off by default though). Or you can do no checking at all ( which is what most probably have been doing in this class all along. And that is/was OK ).
There are several ways of signaling errors in Lisp. See CLtL2 chapter 24 for a full discussion of this topic. The following are three of the more commonly used error signalers.
error format-string &rest argsThis function is used to signal a fatal error. It is impossible to continue from this kind of error. [ Note: error will never return to its caller. ]
Examples are ( you can invoke these at the Listener ) :
(error "Do not pass go, Do not collect $200. Go directly to Jail.") (error "the value of ~A : ~S is not a legal value" 'x "foo" )
cerror continue-format-string error-format-string &rest argsThe error-format-string is displayed upon entry into the debugger. It has the same functionality of the format string argument to
error.
The continue-format-string is displayed in the Restarts Window in MCL (and as one of the options in the initial debugger message in LCL ). The following are two examples.
(cerror "Continue on your merry way" "Halt we are the Borg, resistance is futile...") (defun average ( num-list ) (cond ( (null num-list ) (cerror "Use 0 as the average" "Average of the empty list is undefined.") 0 ) (t (/ (reduce #'+ num-list ) (length num-list)))))For the latter entering
(average '( 1 2 3) is fine. While
entering (average nil ) can be continued and return the default
number.
But sometimes it would be nice to correct the input to a function on the fly and continue. For that see the next function.
Malloc failed due to lack of heap space. Have a nice day. :-)Of course since there is a debugger built into lisp, Lisp can do something slightly better than dump you back at the prompt.
The assert macro in lisp has the following specification:
assert test-form (place...) format-string format-argsIf the test-form fails then the format-string is printed. The place is any legal first argument to a
setf form.
The remainder
is the used to print the error message. After a new value is bound the
test-form is redone.
If the new value isn't legal either, the user is queried
yet again.
(let ( (foo nil ))
(assert (floatp foo )
(foo )
"The variable FOO : ~S is not a float" foo )
foo )
Evaluating this will drop you into the debugger. If you try to continue
at this point you will be prompted to give another value. Give foo the
value 1. This will land you in the debugger yet again. At this point
give foo a value such as 1.23 or some other float. The expression will
return that value since the last line of the let is simply foo. The following
is a slightly more complicated example.
(let ((foo nil )
(bar nil ))
(assert ( and foo bar )
(foo bar )
"Either Foo : ~S or Bar : ~S are nil" foo bar )
(list foo bar ))