[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

exception systems



To evaluate any proposed exception system, we need some idea
of what we want to do with it.  Here are six distinct reasons
we might want an exception system.

****************************************************************

1.  So an application can use exceptions as a control structure
without having to load an SLIB module or use
CALL-WITH-CURRENT-CONTINUATION.

2.  So an application can give up when it detects an untenable
situation.

3.  So an application doesn't have to give up when a predefined
procedure detects and reports an error.

4.  So an application can give meaning to some situation that
the language standards describe as an error.  For example, an
application might want (CAR '()) to evaluate to #f, or (+ LOG EXP)
to be (LAMBDA (X) (+ (LOG X) (EXP X))).
Since there are only two errors that implementations are required
to detect, this usage would almost always be
implementation-dependent.

5.  So an implementation can inline a common case, but take an
exception to handle less common cases.  For example, (+ X 1)
might generate a MIXED-MODE-ARITHMETIC exception if the value
of X is not a small exact integer.  This usage would always be
implementation-dependent.

6.  So an implementation can implement asynchronous interrupts.
For example, an exception might occur when a key is pressed
or a timer reaches 0.  This usage would always be
implementation-dependent.

****************************************************************

It appears to me that the exception system that was proposed last
September by Friedman, Haynes, and Dybvig is barely adequate for
purposes 1 and 2.  I say "barely" because each application would
still have to roll its own method for encoding exceptions (bad
for purpose 1), and there is no way to guard against an accidental
clash of encodings (bad for purpose 2).

Richard Kelsey's proposal is barely adequate for purposes 1, 2,
and 3.  I say "barely" because, although it can recognize when
a predefined procedure signals an error, it has no way to know
which error is being signalled, let alone what might be done
about it.

It seems to me that we're more likely to end up with an useful
exception system if we focus on purposes 4, 5, and 6.  I think
purposes 1, 2, and 3 will be easy to add to any system that can
deal with purposes 4, 5, and 6.

****************************************************************

For reference, here is a list of the errors mentioned by the R4RS.



Error is signalled.

FILE CANNOT BE OPENED

END OF FILE ENCOUNTERED WHILE READING OBJECT



Errors.

DOMAIN ERROR
"It is an error for a procedure to be passed an argument that
the procedure is not explicitly specified to handle"

VIOLATION OF IMPLEMENTATION RESTRICTION
out of storage
unable to represent exact result of procedure
unable to represent exact value of constant
unable to represent inexact result without loss of accuracy (max)
unable to represent result without excessive loss of accuracy
  (exact->inexact, inexact->exact)

SIDE EFFECT TO IMMUTABLE LOCATION (a domain error)
quoted constant
value returned by symbol->string

REFERENCE TO UNBOUND VARIABLE

ASSIGNMENT TO UNBOUND VARIABLE

SYNTAX ERROR
variable appears more than once in formals

VIOLATION OF LETREC RESTRICTION (a kind of unbound variable error)

CAR OR CDR OF THE EMPTY LIST (a domain error)

USE OF ANYTHING BUT AN EXACT INTEGER AS AN INDEX (a domain error)

NO READABLE RESULT FOR NUMBER->STRING (usually a domain error)

READ FROM CLOSED PORT (a domain error)



Errors mentioned by the formal semantics.

undefined variable
wrong number of arguments
out of memory
too few arguments
wrong number of return values
bad procedure
non-numeric argument to <, +
non-pair argument to car, set-car!
immutable argument to set-car!
bad procedure argument to apply
non-list argument to values-list
bad procedure argument (call-with-current-continuation)

****************************************************************

To summarize, there are only a few different general kinds of
"system" errors.  For each general kind of error I will list the
things that I think a handler would need in order to decide what
to do and to do it.  In my opinion, the hard part of designing
an exception system is to design an interface that is capable
of expressing the nature of the problem, and the information
needed for recovery, in a portable way.

SYNTAX ERROR
  continuation
  whether in code (e.g. LOAD) or data (e.g. READ)
  nature of problem (e.g. illegal character: #\[)
  port
  information needed for recovery
    (this is highly implementation-dependent, as it depends
     on the parser technology)

EXTERNAL FILE SYSTEM
  continuation
  whether input (e.g. READ) or output (e.g. WRITE)
  nature of problem (e.g. unable to open file)
  port
  information needed for recovery
    (e.g. the character being written when a write error occurred)

UNBOUND VARIABLE
  continuation
  whether reference or assignment
  name of variable
  information needed for recovery
    (this is implementation-dependent also, though a getter
     and setter for the variable would suffice in some systems)

DOMAIN ERROR
  continuation
  procedure (or alleged procedure, in the case of a bad procedure)
  arguments
  nature of problem (e.g. index out of range: 3rd argument is
    not a legitimate index for 1st argument)

IMPLEMENTATION RESTRICTION
  I think this is usually similar to a domain error

****************************************************************

Will