Exception handlers [was: Traps for module writers]

Daniel LaLiberte (liberte@ncsa.uiuc.edu)
Tue, 26 Nov 1996 15:57:48 -0600 (CST)


Nick Ing-Simmons <nik@tiuk.ti.com> writes:

 > Don't need a keyword - we can use a prototype - wrote this for Tk 
 > yesterday in light of this thread here : 
 > 
 > 
 > # a wrapper on eval {} which turns off user $SIG{__DIE__}
 > sub catch (&)
 > {
 >  my $sub = shift;
 >  eval {local $SIG{'__DIE__'}; &$sub };
 > }

A standard routine like this 'catch' will be useful, but I think the
name should be changed.  In the exceptions.pl file in the Perl
library, 'catch' and 'throw' are defined to act like Lisp's catch and
throw.  A throw of a specific tag is caught by a currently active
catch that says it will catch that tag, and control proceeds after
that catch.  A cleanly defined catch module would be handy.

But another useful Lisp routine is 'unwind-protect' (I'm not
crazy about the name).  It calls some finalization code no matter what
happens in some body code.   A 'protect' call might look like:

  protect { some body code }
    finally { some finalization code }

The 'catch' Nick defined is basically 'protect' without a 'finally'
clause, I think.

More generally still, we need something like Lisp's condition-case.
Exceptions (which might be either names or objects) may be 'raise'd.
Each currently active condition-case is checked until a handler for
the exception is found.  The exceptions that a specific handler will
handle can be specific (e.g. arithmetic-error) or general
(e.g. error).

The condition-case idea can be combined with the unwind-protect and
catch/throw ideas into one general exception handler.  Tags that may
be thrown would just be one kind of exception.  The finalization code, if
present, would be executed no matter what.  So the 'protect' with handlers
might look like:

  protect { some body code }
    when ( exception(s) to handle ) {  handler code }
    when ( exception(s) to handle ) {  handler code }
    finally { finalization code }

I don't know what syntax Perl would allow, or how the
exceptions-to-handle would be specified, but this is the basic idea.
There are more complications regarding whether some exceptions are
continuable (from the point the exception was raised), or whether full
continuations are possible as an even more general mechanism for
building exception handlers and other control constructs.

--
Daniel LaLiberte (liberte@ncsa.uiuc.edu)   (217) 244-0013
National Center for Supercomputing Applications
152 Computing Appliations Building
605 East Springfield Avenue
Champaign, IL 61820