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

Re: a safer and more efficient exception system




   Date: Tue, 23 Apr 1996 14:23:26 +0000
   From: William D Clinger <will@ccs.neu.edu>
   References: <199604190256.WAA15846@sting14>

   This is a rearrangement of Kelsey's proposal, dividing it into
   three distinct systems: an exception system, a condition data
   type, and a restart system. 

   [...]

   Furthermore I have separated exceptions from conditions, and
   have moved multiple inheritance from conditions to exceptions.

   The exception system and restart system are independently useful.
   A condition is just a message they use to communicate.  Conditions
   serve no other purpose.

It would be nice if we didn't have both exceptions and conditions.
What is the advantage of not using one type of exception/condition
object be used for both purposes?

   Compared to Kelsey's proposal, this rearrangement is

     1.  not quite as general.  There are a couple of things you
	 can do with Kelsey's system that you can't do in this
	 system.

Some of the losses are important.  In your proposal every
exception includes a default restart that is invoked by
returning from a handler.  Because of this you cannot raise
an exception and know that the raise call is not going to
return.  I think that this is a real safety problem.

Also, the value of having inheritance for exception types
is greatly reduced.  Instead of being encapsulating in a
data structure (what I called a condition) the information
associated with an exception is passed as additional arguments
to the handlers.  The arguments passed with an exception of a
particular type have to be compatible with those of all of
the exception type's superclasses.  If two exception types
have incompatible argument conventions you cannot make a new
type that is a subclass of both.  Or rather, you can make it
but handlers for the superclasses will break when they get an
instance of the new class.

     2.  safer.  One of the things you can't do is to wedge the
	 entire exception system with just one buggy exception
	 handler.  System exceptions can use the exception system
	 without being sabotaged by bugs in non-system code.

True, but one buggy handler can wreak havoc by returning
value(s) inappropriate to the condition being raised.

The exception handling system from my proposal can be made
much safer by doing the following:

- Have WITH-HANDLER take an as argument an exception type that
  specifies the type of exceptions for which the handler will
  be invoked.

- Specify that raising an exception within a handler invokes
  the handler in scope at the time of the call to WITH-HANDLER
  that installed the first handler.  For example, if in the
  following code HANDLER1 raises a condition of type E, that
  condition will be passed to HANDLER0, not HANDLER1.

  (with-handler e handler0
    (lambda ()
      (with-handler e handler1
        (lambda ()
          (signal (make-condition e))))))


     3.  more efficient.  Signalling and returning from an exception
	 might involve about ten RISC instructions in some
	 implementations.

There you have me.  Out of curiosity, does that ten instructions
include the call to the handler or just the signalling/returning
overhead?

I don't understand why the time to raise an exception, handle it,
and then invoking a restart should need to be on the same order
as the time to do a non-tail-recursive procedure call.  That is
asking a lot.

I will try to address your safety and efficiency concerns with a
revised version of my proposal, but the restarts still won't be
as efficient as your default ones.
                                        -Richard