Conditions

The defined name of this module is condition. The condition system was influenced by the Common Lisp error system [? ] and the Standard ML exception mechanism. It is a simplification of the former and an extension of the latter. Following standard practice, this text defines the actions of functions in terms of their normal behaviour. Where an exceptional behaviour might arise, this has been defined in terms of a condition. However, not all exceptional situations are errors. Following Pitman, we use condition to be a kind of occasion in a program when an exceptional situation has been signalled. An error is a kind of condition|error and condition are also used as terms for the objects that represent exceptional situations. A condition can be signalled continuably by passing a continuation for the resumption to signal. If a continuation is not supplied then the condition cannot be continued. These two categories are characterized as follows:
  1. A condition might be signalled when some limit has been transgressed and some corrective action is needed before processing can resume. For example, memory zone exhaustion on attempting to heap-allocate an item can be corrected by calling the memory management scheme to recover dead space. However, if no space was recovered a new kind of condition has arisen. Another example arises in the use of IEEE floating point arithmetic, where a condition might be signalled to indicate divergence of an operation. A condition should be signalled continuably when there is a strategy for recovery from the condition.
  2. Alternatively, a condition might be signalled when some catastrophic situation is recognized, such as the memory manager being unable to allocate more memory or unable to recover sufficient memory from that already allocated. A condition should be signalled non-continuably when there is no reasonable way to resume processing.
A condition class is defined using defcondition (see Section ). The definition of a condition causes the creation of a new class of condition. A condition is signalled using the function signal, which has two required arguments and one optional argument: an instance of a condition, a resume continuation or the empty list, the latter signifying a non-continuable signal, and a thread. A condition can be handled using the special form with-handler, which takes a function, the handler function, and a sequence of forms to be protected. The initial condition class hierarchy is as follows: <condition> <execution-condition> <invalid-operator> <cannot-update-setter> <no-setter> <domain-condition> <range-condition> <environment-condition> <arithmetic-condition> <division-by-zero> <conversion-condition> <no-converter> <stream-condition> <syntax-error> <thread-condition> <thread-already-started> <wrong-thread-continuation> <wrong-condition-class> <telos-condition> <no-next-method> <generic-function-condition> <non-congruent-lambda-lists> <incompatible-method-domain> <no-applicable-method> <method-domain-clash>

Table of contents

call-next-handler conditionp <condition>
defcondition initialize signal
with-handler <wrong-condition-class>

Condition Classes

defcondition : defining formINDEX

Syntax

defcondition form = '(', 'defcondition', condition class name, condition superclass name, {slot name}, ')';

Remarks

Arguments

condition class name
An identifier naming a binding to be initialized with the new condition class.
condition superclass name
An indentifier naming a binding of a class to be used as the superclass of the new condition class.
slot names
A sequence of keywords used to name and to identify additional slots begin defined for this condition class.

Remarks

This defining form defines a new condition class. The first argument is the identifier to which the new condition class will be bound. The second is the identifier of the superclass of the new condition class and an init-option is an identifier followed by its (default) initial value. If superclass-name is (), the superclass is taken to be <condition>. Otherwise superclass-name must be <condition> or the name of one of its subclasses.

<condition> : classINDEX

Initialization options

message : <string>
A string, which may contain format directives which will be filled in with the corresponding message arguments.
message-arguments : <list>
A list of objects to be used in processing the message format string.

Remarks

The class which is the superclass of all condition classes.

conditionp : functionINDEX

Arguments

object
An object to examine.

Result

Returns object if it is a condition, otherwise ().

initialize : methodINDEX

Specialized arguments

(condition <condition>)
A condition.
initlist
A list of initialization options as follows:
message : <string>
A string, which may contain format directives which will be filled in with the corresponding message arguments.
message-arguments : <list>
A list of objects to be used in processing the message format string.

Result

A new, initialized condition.

Remarks

First calls call-next-method to carry out initialization specified by superclasses then does the condition specific initialization.

<wrong-condition-class> : <thread-condition>INDEX

Initialization options

condition : condition
A condition.
Signalled by signal if the given condition is not an instance of the condition class <thread-condition>.

Condition Signalling and Handling

Conditions are handled by a function called a handler. Handlers are established dynamically and have dynamic scope and extent. Thus, when a condition is signalled, the processor will call the nearest enclosing handler. Handlers are established by the special form with-handler.

signal : functionINDEX

Arguments

condition
The condition to be signalled.
[thread]
If this argument is not supplied, the condition is signalled on the thread which called signal, otherwise, thread indicates the thread on which condition is to be signalled.

Remarks

Called to indicate that a specified condition has arisen during the execution of a program. If the third argument is not supplied, signal calls the nearest enclosing handler with condition. If the second argument is supplied, signal registers the specified condition to be signalled on thread. The condition must be an instance of the condition class <thread-condition>, otherwise an error is signalled (condition class: <wrong-condition-class>) on the thread calling signal. A signal on a determined thread has no effect on either the signalled or signalling thread except in the case of the above error.

See also:

thread-reschedule, thread-value, with-handler.

call-next-handler : special formINDEX

Syntax

call next handler form = '(', 'call-next-handler', ')';

Remarks

The call-next-handler special form calls the next enclosing handler. It is an error to evaluate this form other than within an established handler function. The call-next-handler special form is normally used when a handler function does not know how to deal with the class of condition. However, it may also be used to combine handler function behaviour in a similar but orthogonal way to call-next-method (assuming a generic handler function).

with-handler : special formINDEX

Syntax

with handler form = '(', 'with-handler', handler function, {form}, ')'; handler function = level 0 expression;

Arguments

handler function
The result of evaluating the handler function expression must be either a function or a generic function. This function will be called if a condition is signalled during the dynamic extent of protected-forms and there are no intervening handler functions which accept or resume the condition. A handler function takes two arguments: a condition, and a resume function/continuation. The condition is the condition object that was passed to signal as its first argument. The resume continuation is the continuation (or ()) that was given to signal as its second argument.
forms
The sequence of forms whose execution is protected by the handler function specified above.

Result

The value of the last form in the sequence of forms.

Remarks

A with-handler form is evaluated in three steps:
  1. The new handler-function is evaluated. This now identifies the nearest enclosing handler and shadows the previous nearest enclosing handler.
  2. The sequence of forms is evaluated in order and the value of the last one is returned as the result of the with-handler expression.
  3. the handler function is disestablished as the nearest enclosing handler, and the previous handler function is restored as the nearest enclosing.
The above is the normal behaviour of with-handler. The exceptional behaviour of with-handler happens when there is a call to signal during the evaluation of protected-form. signal calls the nearest enclosing handler-function passing on the first two arguments given to signal. The handler-function is executed in the dynamic extent of the call to signal. However, any calls to signals occurring during the execution of handler-function are dealt with by the nearest enclosing handler outside the extent of the form which established handler-function. It is an error if there is no enclosing handler. In this circumstance the identified error is delivered to the configuration to be dealt with in an implementation-defined way. Errors arising in the dynamic extent of the handler function are signalled in the dynamic extent of the original signal but are handled in the enclosing dynamic extent of the handler.

Examples

There are three ways in which a handler function can respond:
  1. The error is very serious and the computation must be abandoned; this is likely to be characterised by a non-local exit from the handler function.
  2. The situation can be corrected by the handler, so it does and then returns. Thus the call to signal returns with the result passed back from the handler function.
  3. The handler function does not know how to deal with the class of condition signalled; control is passed explicitly to the next enclosing handler via the call-next-handler special form.
An illustration of the use of all three cases is given here: (defgeneric error-handler (condition) method: (((c <serious-error>)) ... abort thread ...) method: (((c <fixable-situation>)) ...apply fix and return ... ) method: (((c <condition>) (call-next-handler)))) (with-handler error-handler ;; the protected expression (something-which-might-signal-an-error))

See also:

signal.
Julian Padget, jap@maths.bath.ac.uk, this version November 28, 1996