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

Re: exception systems



   Date: Tue, 16 Apr 1996 14:58:52 +0000
   From: William D Clinger <will@ccs.neu.edu>

   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.

It is laudable to make goals explicit.  In a minimal language like
Scheme, the design of a new feature should be restricted to
accomplishing tasks which the previous revision of specification fails
to support.  In our rush to design and implement we may have adopted
some goals which closer examination reveals to be unnecessary or
ill-founded.

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

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

Avoiding the loading of files (assuming that this condition is not
directed solely to SLIB files) is a major new restriction on
implementations.  Many of SCM's procedures are defined in its Scheme
initialization file.  What large benefit justifies restricting
implementations thus?

If this is an attempt to have the exception system operable to handle
errors during intialization, then it is a vain hope.  Reflexive
systems always must have some code which bypasses fully general
dispatch.

The lines separating loading from other operations are vague.  If I
compile the initialization file into my interpreter and load from that
string, is it loading?  What if I EVAL the string?  After my program
is invoked, if it dynamically link/loads a compiled object file with
the initialization code, is it loading?

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

This is the situation currently.  An application program has no
recourse when an error is signaled.

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

OK.  We would like a program to be able to continue operating even
when some types of errors are signaled.

   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))).

Scheme programs can already can accomplish these tasks by redefining
CAR and +.  By defining them, a program declares to a compiler that
these procedures can behave differently from the built-in procedures.
To redefine built-in procedures by creating exception handlers would
seem to make compiling extremely difficult.  Procedures would never be
closed -- a new exception handler could change the behavior of a
compiled procedure at any time.

   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.

The objections to 4 apply here too.  Exceptions seem a very roundabout
way to extend arithmetic operations to new types.  Don't `object' or
`type' systems specify such extensions more cleanly?

   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.

OK.  We would like a program to be able to respond to asynchronous
events.

			     -=-=-=-=-=-

I think goals 2, 3 and 6 are well-founded and desirable.  It would
help me to understand handlers to see some examples of exception
handlers from real programs.

As for goal 6, a global timer resource is of limited usefullness
because a program using the timer must know that no other code uses
it.  This feature might instead be designed as time limits for
operations, much like select() in the C-library.

An example of such a construct might be:

 (WITH-TIME-LIMIT <seconds> <thunk> <handler>)

 Calls procedure <thunk> and returns its value.  If integer <seconds>
 seconds pass before <thunk> returns, the procedure <handler> is
 instead called with the continuation of <thunk>; and <handler>'s value
 is returned.


-- 
			     -=-=-=-=-=-
I am a guest and *not* a member of the MIT Artificial Intelligence Lab.
      My actions and comments do not reflect in any way on MIT.