This section describes functions, macros, variables, and condition types associated with the Common Lisp Condition System.
The functions in this section provide various mechanisms for signaling warnings, breaks, continuable errors, and fatal errors.
Invokes the signal facility on a condition. If the condition is not handled, (invoke-debugger condition) is executed. As a consequence of calling invoke-debugger, error never directly returns to its caller; the only exit from this function can come by non-local transfer of control in a handler or by use of an interactive debugging command.
If datum is a condition, then that condition is used directly. In this case, it is an error for the list of arguments to be non-empty; that is, error must have been called with exactly one argument, the condition.
If datum is a condition type (a class or class name), then the condition used is effectively the result of (apply #’make-condition datum arguments).
If datum is a string, then the condition used is effectively the result of
The function cerror invokes the error facility on a condition. If the condition is not handled, (invoke-debugger condition) is executed. While signaling is going on, and while control is in the debugger (if it is reached), it is possible to continue program execution (thereby returning from the call to cerror) using the continue restart.
If datum is a condition, then that condition is used directly. In this case, the list of arguments need not be empty, but will be used only with the continue-format-string and will not be used to initialize datum.
If datum is a condition type (a class or class name), then the condition used is effectively the result of (apply #’make-condition datum arguments).
If datum is a string, then the condition used is effectively the result of
The continue-format-string must be a string. Note that if datum is not a string, then the format arguments used by the continue-format-string will still be the list of arguments (which is in keyword format if datum is a condition type). In this case, some care may be necessary to set up the continue-format-string correctly. The format directive ~*, which ignores and skips over format arguments, may be particularly useful in this situation.
The value returned by cerror is nil.
Invokes the signal facility on a condition. If the condition is not handled, signal returns nil.
If datum is a condition, then that condition is used directly. In this case, it is an error for the list of arguments to be non-empty; that is, signal must have been called with exactly one argument, the condition.
If datum is a condition type (a class or class name), then the condition used is effectively the result of (apply #’make-condition datum arguments).
If datum is a string, then the condition used is effectively the result of
Note that if (typep condition *break-on-signals*) is true, then the debugger will be entered prior to beginning the process of signaling. The continue restart function may be used to continue with the signaling process; the restart is associated with the signaled condition as if by use of with-condition-restarts. This is true also for all other functions and macros that signal conditions, such as warn, error, cerror, assert, and check-type.
During the dynamic extent of a call to signal with a particular condition, the effect of calling signal again on that condition object for a distinct abstract event is not defined. For example, although a handler may resignal a condition in order to allow outer handlers first shot at handling the condition, two distinct asynchronous keyboard events must not signal an the same (eq) condition object at the same time.
For further details about signaling and handling, see the discussion of condition handlers in section 29.3.17.
This variable is intended primarily for use when the user is debugging programs that do signaling. The value of *break-on-signals* should be suitable as a second argument to typep, that is, a type or type specifier.
When (typep condition *break-on-signals*) is true, then calls to signal (and to other advertised functions such as error that implicitly call signal) will enter the debugger prior to signaling that condition. The continue restart may be used to continue with the normal signaling process; the restart is associated with the signaled condition as if by use of with-condition-restarts.
Note that nil is a valid type specifier. If the value of *break-on-signals* is nil, then signal will never enter the debugger in this implicit manner.
When setting this variable, the user is encouraged to choose the most restrictive specification that suffices. Setting this flag effectively violates the modular handling of condition signaling that this chapter seeks to establish. Its complete effect may be unpredictable in some cases, since the user may not be aware of the variety or number of calls to signal that are used in programs called only incidentally.
By default—and certainly in any “production” use—the value of this variable should be nil, both for reasons of performance and for reasons of modularity and abstraction.
These facilities are designed to make it convenient for the user to insert error checks into code.
A check-type form signals an error of type type-error if the contents of place are not of the desired type.
If a condition is signaled, handlers of this condition can use the functions type-error-datum and type-error-expected-type to access the contents of place and the typespec, respectively.
This function can return only if the store-value 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 with-condition-restarts.
If store-value is called, check-type will store the new value that is the argument to store-value (or that is prompted for interactively by the debugger) in place and start over, checking the type of the new value and signaling another error if it is still not 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 the string is not supplied, it is computed automatically from the 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 the place, its contents, and the desired type. _____________________________________________________________________
Implementation note: An implementation may choose to generate a somewhat differently worded error message if it recognizes that place is of a particular form, such as one of the arguments to the function that called check-type.
An assert form signals an error if the value of the test-form is nil. Continuing from this error using the continue restart will allow the user to alter the values of some variables, and assert will then start over, evaluating the test-form again. (The restart is associated with the signaled condition as if by use of with-condition-restarts.) assert returns nil.
The test-form may be 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 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).
The datum and arguments are evaluated only if an error is to be signaled, and re-evaluated if the error is to be signaled again.
If datum is a condition, then that condition is used directly. In this case, it is an error to specify any arguments.
If datum is a condition type (a class or class name), then the condition used is effectively the result of (apply #’make-condition datum (list {argument}* )).
If datum is a string, then the condition used is effectively the result of
If datum is omitted, then a condition of type simple-error is constructed using the test-form as data. For example, the following might be used:
Note that the test-form itself, and not its value, is used as the format argument. ________________________________________________________________
Implementation note: The debugger need not include the test-form in the error message, and any places 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.
Here is an example of the use of assert:
The syntax for etypecase and ctypecase is the same as for typecase, except that no otherwise clause is permitted. Similarly, the syntax for ecase and ccase is the same as for case except for the otherwise clause.
etypecase and ecase are similar to typecase and case, respectively, but signal a non-continuable error rather than returning nil if no clause is selected.
ctypecase and ccase are also similar to typecase and case, respectively, but signal a continuable error if no clause is selected.
This control construct is similar to typecase, but no explicit otherwise or t clause is permitted. If no clause is satisfied, etypecase signals an error (of type type-error) with a message constructed from the clauses. It is not permissible to continue from this error. To supply an error message, the user should use typecase with an otherwise clause containing a call to error. The name of this function stands for “exhaustive type case” or “error-checking type case.”
Example:
This control construct is similar to typecase, but no explicit otherwise or t clause is permitted.
The keyplace must be a generalized variable reference acceptable to setf. If no clause is satisfied, ctypecase signals an error (of type type-error) with a message constructed from the clauses. This error may be continued using the store-value restart. The argument to store-value is stored in keyplace and then ctypecase starts over, making the type tests again. Subforms of keyplace may be evaluated multiple times. If the store-value restart is invoked interactively, the user will be prompted for the value to be used.
The name of this function is mnemonic for “continuable (exhaustive) type case.”
Example:
This control construct is similar to case, but no explicit otherwise or t clause is permitted. If no clause is satisfied, ecase signals an error (of type type-error) with a message constructed from the clauses. It is not permissible to continue from this error. To supply an error message, the user should use case with an otherwise clause containing a call to error. The name of this function stands for “exhaustive case” or “error-checking case.”
Example:
This control construct is similar to case, but no explicit otherwise or t clause is permitted.
The keyplace must be a generalized variable reference acceptable to setf. If no clause is satisfied, ccase signals an error (of type type-error) with a message constructed from the clauses. This error may be continued using the store-value restart. The argument to store-value is stored in keyplace and then ccase starts over, making the type tests again. Subforms of keyplace may be evaluated multiple times. If the store-value restart is invoked interactively, the user will be prompted for the value to be used.
The name of this function is mnemonic for “continuable (exhaustive) case.” _____________________________________________________________________
Implementation note: The type-error signaled by ccase and ecase is free to choose any representation of the acceptable argument type that it wishes for placement in the expected-type slot. It will always work to use type (member . keys), but in some cases it may be more efficient, for example, to use a type that represents an integer subrange or a type composed using the or type specifier.
These macros allow a program to gain control when a condition is signaled.
Executes the given expression in a context where various specified handlers are active.
Each typespec may be any type specifier. If during the execution of the expression a condition is signaled for which there is an appropriate clause—that is, one for which (typep condition ’typespec) is true—and if there is no intervening handler for conditions of that type, then control is transferred to the body of the relevant clause (unwinding the dynamic state appropriately in the process) and the given variable var is bound to the condition that was signaled. If no such condition is signaled and the computation runs to completion, then the values resulting from the expression are returned by the handler-case form.
If more than one case is provided, those cases are made accessible in parallel. That is, in
if the first clause (containing form1) has been selected, the handler for the second is no longer visible (and vice versa).
The cases are searched sequentially from top to bottom. If a signaled condition matches more than one case (possible if there is type overlap) the earlier of the two cases will be selected.
If the variable var is not needed, it may be omitted. That is, a clause such as
may be written using the following shorthand notation:
If there are no forms in a selected case, the case returns nil. Note that
is approximately equivalent to
[Note the use of “gensyms” such as #:block-1 as block names, variables, and tagbody tags in this example, and the use of #n= and #n# read-macro syntax to indicate that the very same gensym appears in multiple places.—GLS]
As a special case, the typespec can also be the symbol :no-error in the last clause. If it is, it designates a clause that will take control if the expression returns normally. In that case, a completely general lambda-list may follow the symbol :no-error, and the arguments to which the lambda-list parameters are bound are like those for multiple-value-call on the return value of the expression. For example,
is approximately equivalent to
Examples of the use of handler-case:
Executes its body in a context that handles conditions of type error by returning control to this form. If no such condition is signaled, any values returned by the last form are returned by ignore-errors. Otherwise, two values are returned: nil and the error condition that was signaled.
ignore-errors could be defined by
Executes body in a dynamic context where the given handler bindings are in effect. Each typespec may be any type specifier. Each handler form should evaluate to a function to be used to handle conditions of the given type(s) during execution of the forms. This function should take a single argument, the condition being signaled.
If more than one binding is specified, the bindings are searched sequentially from top to bottom in search of a match (by visual analogy with typecase). If an appropriate typespec is found, the associated handler is run in a context where none of the handler bindings are visible (to avoid recursive errors). For example, in the case of
if an unbound variable error is signaled in the body (and not handled by an intervening handler), the first function will be called. If any other kind of error is signaled, the second function will be called. In either case, neither handler will be active while executing the code in the associated function.
[The contents of this section are still a subject of some debate within X3J13. The reader may wish to take this section with a grain of salt, two aspirin tablets, and call a hacker in the morning.—GLS]
Defines a new condition type called name, which is a subtype of each given parent-type. Except as otherwise noted, the arguments are not evaluated.
Objects of this condition type will have all of the indicated slots, plus any additional slots inherited from the parent types (its superclasses). If the slots list is omitted, the empty list is assumed.
A slot must have the form
make-condition will accept keywords (in the keyword package) with the print name of any of the designated slots, and will initialize the corresponding slots in conditions it creates.
Accessors are created according to the same rules as used by defclass.
The valid options are as follows:
The doc-string should be either nil or a string that describes the purpose of the condition type. If this option is omitted, nil is assumed. Calling (documentation ’name ’type) will retrieve this information.
If exp is not a literal string, it must be a suitable argument to the function special operator. The expression (function exp) will be evaluated in the current lexical environment. It should produce a function of two 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 *print-escape* is nil.
If exp is a literal string, it is shorthand for
[That is, a function is provided that will simply write the given string literally to the stream, regardless of the particular condition object supplied.—GLS]
The :report 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 specified, information about how to report this type of condition will be inherited from the parent-type.
[X3J13 voted in March 1989 to integrate the Condition System and the Object System. In the original Condition System proposal, define-condition allowed only one parent-type (the inheritance structure was a simple hierarchy). Slot descriptions were much simpler, even simpler than those for defstruct:
Not now part of Common Lisp. As with defstruct, this sets up automatic prefixing of the names of slot accessors. Also as in defstruct, the default behavior is to use the name of the new type, name, followed by a hyphen. (Generated names are interned in the package that is current at the time that the define-condition is processed).
One consequence of the vote was to make define-condition slot descriptions like those of defclass.—GLS]
Here are some examples of the use of define-condition.
The following form defines a condition of type peg/hole-mismatch that inherits from a condition type called blocks-world-error:
The new type has slots peg-shape and hole-shape, so make-condition will accept :peg-shape and :hole-shape keywords. The with-slots macro may be used to access the peg-shape and hole-shape slots, as illustrated in the :report information.
Here is another example. This defines a condition called machine-error that inherits from error:
Building on this definition, we can define a new error condition that is a subtype of machine-error for use when machines are not available:
We may now define a still more specific condition, built upon machine-not-available-error, that provides a default for machine-name but does not provide any new slots or report information. It just gives the machine-name slot a default initialization:
Note that since no :report clause was given, the information inherited from machine-not-available-error will be used to report this type of condition.
The function make-condition is the basic means for creating condition objects.
Constructs a condition object of the given type using slot-initializations as a specification of the initial value of the slots. The newly created condition is returned.
The slot-initializations are alternating keyword/value pairs. For example:
The lowest-level form that creates restart points is called restart-bind. The restart-case macro is an abstraction that addresses many common needs for restart-bind while offering a more palatable syntax. See also with-simple-restart. The function that transfers control to a restart point established by one of these macros is called invoke-restart.
All restarts have dynamic extent; a restart does not survive execution of the form that establishes it.
This is shorthand for one of the most common uses of restart-case.
If the restart designated by name is not invoked while executing the forms, all values returned by the last form are returned. If that restart is invoked, control is transferred to the with-simple-restart form, which immediately returns the two values nil and t.
The name may be nil, in which case an anonymous restart is established.
with-simple-restart could be defined by
Here is an example of the use of with-simple-restart.
Remark: Some readers may wonder what ought to be done by the “abort” key (or whatever the implementation’s interrupt key is—Control-C or Control-G, for example). Such interrupts, whether synchronous or asynchronous in nature, are beyond the scope of this chapter and indeed are not currently addressed by Common Lisp at all. This may be a topic worth standardizing under separate cover. Here is some speculation about some possible things that might happen.
An implementation might simply call abort or break directly without signaling any condition.
Another implementation might signal some condition related to the fact that a key had been pressed rather than to the action that should be taken. This is one way to allow user customization. Perhaps there would be an implementation-dependent keyboard-interrupt condition type with a slot containing the key that was pressed—or perhaps there would be such a condition type, but rather than its having slots, different subtypes of that type with names like keyboard-abort, keyboard-break, and so on might be signaled. That implementation would then document the action it would take if user programs failed to handle the condition, and perhaps ways for user programs to usefully dismiss the interrupt.__
Implementation note: Implementors are encouraged to make sure that there is always a restart named abort around any user code so that user code can call abort at any time and expect something reasonable to happen; exactly what the reasonable thing is may vary somewhat. Typically, in an interactive program, invoking abort should return the user to top level, though in some batch or multi-processing situations killing the running process might be more appropriate.
The expression is evaluated in a dynamic context where the clauses have special meanings as points to which control may be transferred. If the expression finishes executing and returns any values, all such values are simply returned by the restart-case form. While the expression is running, any code may transfer control to one of the clauses (see invoke-restart). If a transfer occurs, the forms in the body of that clause will be evaluated and any values returned by the last such form will be returned by the restart-case form.
As a special case, if the expression is a list whose car is signal, error, cerror, or warn, then with-condition-restarts is implicitly used to associate the restarts with the condition to be signaled. For example,
is equivalent to
If there are no forms in a selected clause, restart-case returns nil.
The case-name may be nil or a symbol naming this restart.
It is possible to have more than one clause use the same case-name. In this case, the first clause with that name will be found by find-restart. The other clauses are accessible using compute-restarts. [In this respect, restart-case is rather different from case!—GLS]
Each arglist is a normal lambda-list containing parameters to be bound during the execution of its corresponding forms. These parameters are used to pass any necessary data from a call to invoke-restart to the restart-case clause.
By default, invoke-restart-interactively will pass no arguments and all parameters must be optional in order to accommodate interactive restarting. However, the parameters need not be optional if the :interactive keyword has been used to inform invoke-restart-interactively about how to compute a proper argument list.
The valid keyword value pairs are the following:
The fn must be a suitable argument for the function special operator. The expression (function fn) will be evaluated in the current lexical environment. It should produce a function of one argument, a condition. If this function returns nil when given some condition, functions such as find-restart, compute-restart, and invoke-restart will not consider this restart when searching for restarts associated with that condition. If this pair is not supplied, it is as if
were used for the fn.
The fn must be a suitable argument for the function special operator. The expression (function fn) will be evaluated in the current lexical environment. It should produce a function of no arguments that returns arguments to be used by invoke-restart-interactively when invoking this function. This function will be called in the dynamic environment available prior to any restart attempt. It may interact with the user on the stream in *query-io*.
If a restart is invoked interactively but no :interactive option was supplied, the argument list used in the invocation is the empty list.
If exp is not a literal string, it must be a suitable argument to the function special operator. The expression (function exp) will be evaluated in the current lexical environment. It should produce a function of one argument, a stream, that prints on the stream a description of the restart. This function is called whenever the restart is printed while *print-escape* is nil.
If exp is a literal string, it is shorthand for
[That is, a function is provided that will simply write the given string literally to the stream.—GLS]
If a named restart is asked to report but no report information has been supplied, the name of the restart is used in generating default report text.
When *print-escape* is nil, the printer will use the report information for a restart. For example, a debugger might announce the action of typing “:continue” by executing the equivalent of
which might then display as something like
It is an error if an unnamed restart is used and no report information is provided. ____________________________________________________________
Rationale: Unnamed restarts are required to have report information on the grounds that they are generally only useful interactively, and an interactive option that has no description is of little value.
Implementation note: Implementations are encouraged to warn about this error at compilation time.
At run time, this error might be noticed when entering the debugger. Since signaling an error would probably cause recursive entry into the debugger (causing yet another recursive error, and so on), it is suggested that the debugger print some indication of such problems when they occur, but not actually signal errors.
Note that
is essentially equivalent to
[Note the use of “gensyms” such as #:block-1 as block names, variables, and tagbody tags in this example, and the use of #n= and #n# read-macro syntax to indicate that the very same gensym appears in multiple places.—GLS]
Here are some examples of the use of restart-case.
The first and second examples are equivalent from the point of view of someone using the interactive debugger, but they differ in one important aspect for non-interactive handling. If a handler “knows about” named restarts, as in, for example,
then only the first example, and not the second, will have control transferred to its correction clause, since only the first example uses a restart named new-function.
Here is a more complete example:
Assuming that use-food and use-color have been defined as
a handler can then restart from the error in either of two ways. It may correct the color or correct the food. For example:
Here is an example using handler-bind and restart-case that refers to a condition type foo-error, presumably defined elsewhere:
Executes a body of forms in a dynamic context where the given restart bindings are in effect.
Each name may be nil to indicate an anonymous restart, or some other symbol to indicate a named restart.
Each function is a form that should evaluate to a function to be used to perform the restart. If invoked, this function may either perform a non-local transfer of control or it may return normally. The function may take whatever arguments the programmer feels are appropriate; it will be invoked only if invoke-restart is used from a program, or if a user interactively asks the debugger to invoke it. In the case of interactive invocation, the :interactive-function option is used.
The valid keyword value pairs are as follows:
The form will be evaluated in the current lexical environment and should return a function of one argument, a condition. If this function returns nil when given some condition, functions such as find-restart, compute-restart, and invoke-restart will not consider this restart when searching for restarts associated with that condition. If this pair is not supplied, it is as if
were used for the form.
The form will be evaluated in the current lexical environment and should return a function of no arguments that constructs a list of arguments to be used by invoke-restart-interactively when invoking this restart. The function may prompt interactively using *query-io* if necessary.
The form will be evaluated in the current lexical environment and should return a function of one argument, a stream, that prints on the stream a summary of the action this restart will take. This function is called whenever the restart is printed while *print-escape* is nil.
The value of condition-form should be a condition C and the value of restarts-form should be a list of restarts (R1 R2 ...). The forms of the body are evaluated as an implicit progn. While in the dynamic context of the body, an attempt to find a restart associated with a particular condition C′ will consider the restarts R1, R2, … if C′ is eq to C.
Usually this macro is not used explicitly in code, because restart-case handles most of the common uses in a way that is syntactically more concise.
[The X3J13 vote left it unclear whether with-condition-restarts permits declarations to appear at the heads of its body. I believe that was the intent, but this is only my interpretation.—GLS]
The following functions determine what restarts are active and invoke restarts.
Uses the dynamic state of the program to compute a list of the restarts that are currently active. See restart-bind.
If condition is nil or not supplied, all outstanding restarts are returned. If condition is not nil, only restarts associated with that condition are returned.
Each restart represents a function that can be called to perform some form of recovery action, usually a transfer of control to an outer point in the running program. Implementations are free to implement these objects in whatever manner is most convenient; the objects need have only dynamic extent (relative to the scope of the binding form that instantiates them).
The list that results from a call to compute-restarts is ordered so that the inner (that is, more recently established) restarts are nearer the head of the list.
Note, too, that compute-restarts returns all valid restarts, including anonymous ones, even if some of them have the same name as others and would therefore not be found by find-restart when given a symbol argument.
Implementations are permitted, but not required, to return different (that is, non-eq) lists from repeated calls to compute-restarts while in the same dynamic environment. It is an error to modify the list that is returned by compute-restarts.
Searches for a particular restart in the current dynamic environment.
If condition is nil or not supplied, all outstanding restarts are considered. If condition is not nil, only restarts associated with that condition are considered.
If the restart-identifier is a non-nil symbol, then the innermost (that is, most recently established) restart with that name is returned; nil is returned if no such restart is found.
If restart-identifier is a restart object, then it is simply returned, unless it is not currently active, in which case nil is returned.
Although anonymous restarts have a name of nil, it is an error for the symbol nil to be given as the restart-identifier. Applications that would seem to require this should be rewritten to make appropriate use of compute-restarts instead.
Calls the function associated with the given restart-identifier, passing any given arguments. The restart-identifier must be a restart or the non-null name of a restart that is valid in the current dynamic context. If the argument is not valid, an error of type control-error will be signaled. ___________________________
Implementation note: Restart functions call this function, not vice versa.
Calls the function associated with the given restart-identifier, prompting for any necessary arguments. The restart-identifier must be a restart or the non-null name of a restart that is valid in the current dynamic context. If the argument is not valid, an error of type control-error will be signaled.
The function invoke-restart-interactively will prompt for arguments by executing the code provided in the :interactive keyword to restart-case or :interactive-function keyword to restart-bind.
If no :interactive or :interactive-function option has been supplied in the corresponding restart-case or restart-bind, then it is an error if the restart takes required arguments. If the arguments are optional, an empty argument list will be used in this case.
Once invoke-restart-interactively has calculated the arguments, it simply performs (apply #’invoke-restart restart-identi er arguments).
invoke-restart-interactively is used internally by the debugger and may also be useful in implementing other portable, interactive debugging tools.
Warnings are a subclass of errors that are conventionally regarded as “mild.”
Warns about a situation, by signaling a condition of type warning.
If datum is a condition, then that condition is used directly. In this case, if the condition is not of type warning or arguments is non-nil, an error of type type-error is signaled.
If datum is a condition type (a class or class name), then the condition used is effectively the result of (apply #’make-condition datum arguments). This result must be of type warning or an error of type type-error is signaled.
If datum is a string, then the condition used is effectively the result of
The precise mechanism for warning is as follows.
While the warning condition is being signaled, the muffle-warning restart is established for use by a handler to bypass further action by warn (that is, to cause warn to immediately return nil).
As part of the signaling process, if (typep condition *break-on-signals*) is true, then a break will occur prior to beginning the signaling process.
Common Lisp has the following restart functions built in.
This function transfers control to the restart named abort. If no such restart exists, abort signals an error of type control-error.
If condition is nil or not supplied, all outstanding restarts are considered. If condition is not nil, only restarts associated with that condition are considered.
The purpose of the abort restart is generally to allow control to return to the innermost “command level.”
This function transfers control to the restart named continue. If no such restart exists, continue returns nil.
If condition is nil or not supplied, all outstanding restarts are considered. If condition is not nil, only restarts associated with that condition are considered.
The continue restart is generally part of simple protocols where there is a single “obvious” way to continue, as with break and cerror. Some user-defined protocols may also wish to incorporate it for similar reasons. In general, however, it is more reliable to design a special-purpose restart with a name that better suits the particular application.
This function transfers control to the restart named muffle-warning. If no such restart exists, muffle-warning signals an error of type control-error.
If condition is nil or not supplied, all outstanding restarts are considered. If condition is not nil, only restarts associated with that condition are considered.
warn sets up this restart so that handlers of warning conditions have a way to tell warn that a warning has already been dealt with and that no further action is warranted.
This function transfers control (and one value) to the restart named store-value. If no such restart exists, store-value returns nil.
If condition is nil or not supplied, all outstanding restarts are considered. If condition is not nil, only restarts associated with that condition are considered.
The store-value restart is generally used by handlers trying to recover from errors of types such as cell-error or type-error, where the handler may wish to supply a replacement datum to be stored permanently.
This function transfers control (and one value) to the restart named use-value. If no such restart exists, use-value returns nil.
If condition is nil or not supplied, all outstanding restarts are considered. If condition is not nil, only restarts associated with that condition are considered.
The use-value restart is generally used by handlers trying to recover from errors of types such as cell-error, where the handler may wish to supply a replacement datum for one-time use.
Common Lisp does not specify exactly what a debugger is or does, but it does provide certain means for indicating intent to transfer control to a supervisory or debugging facility.
The function break prints the message described by the format-string and format-arguments and then goes directly into the debugger without allowing any possibility of interception by programmed error-handling facilities.
If no format-string is supplied, a suitable default will be generated.
If continued, break returns nil.
Note that break is presumed to be used as a way of inserting temporary debugging “breakpoints” in a program, not as a way of signaling errors; it is expected that continuing from a break will not trigger any unusual recovery action. For this reason, break does not take the additional format control string that cerror takes as its first argument. This and the lack of any possibility of interception by programmed error handling are the only program-visible differences between break and cerror. The user interface aspects of these functions are permitted to vary more widely; for example, it is permissible for a read-eval-print loop to be entered by break rather than by the conventional debugger.
break could be defined by
Attempts interactive handling of its argument, which must be a condition.
If the variable *debugger-hook* is not nil, it will be called as a function on two arguments: the condition being handled and the value of *debugger-hook*. If a hook function returns normally, the standard debugger will be tried.
The standard debugger will never directly return. Return can occur only by a special transfer of control, such as the use of a restart. _____________________
Remark: The exact way in which the debugger interacts with users is expected to vary considerably from system to system. For example, some systems may use a keyboard interface, while others may use a mouse interface. Of those systems using keyboard commands, some may use single-character commands and others may use parsed line-at-a-time commands. The exact set of commands will vary as well. The important properties of a debugger are that it makes information about the error accessible and that it makes the set of apparent restarts easily accessible.
It is desirable to have a mode where the debugger allows other features, such as the ability to inspect data, stacks, etc. However, it may sometimes be appropriate to have this kind of information hidden from users. Experience on the Lisp Machines has shown that some users who are not programmers develop a terrible phobia of debuggers. The reason for this usually may be traced to the fact that the debugger is very foreign to them and provides an overwhelming amount of information of interest only to programmers. With the advent of restarts, there is a clear mechanism for the construction of “friendly” debuggers. Programmers can be taught how to get to the information they need for debugging, but it should be possible to construct user interfaces to the debugger that are natural, convenient, intelligible, and friendly even to non-programmers. ______
This variable should hold either nil or a function of two arguments, a condition and the value of *debugger-hook*. This function may either handle the condition (transfer control) or return normally (allowing the standard debugger to run).
Note that, to minimize recursive errors while debugging, *debugger-hook* is bound to nil when calling this function. When evaluating code typed in by the user interactively, the hook function may want to bind *debugger-hook* to the function that was its second argument so that recursive errors can be handled using the same interactive facility.