From: Chip Salzenberg <[EMAIL PROTECTED]>
   Date: Sat, 24 Jun 2006 21:56:32 -0700

   On Sat, Jun 24, 2006 at 11:18:41PM -0400, Bob Rogers wrote:
   >  . . . I even intend to use continations to implement THROW and CATCH; I
   > just won't be able to expose them to users via standard Lisp constructs.
   > So, yes, I could install the equivalent of an UNDO block around the Lisp
   > code that does whatever Parrot maintenance is required on the Parrot
   > exception object (which, it now occurs to me, may need to be distinct
   > from the Lisp condition object).  But would I really need to do anything
   > here?  If an exception is caught by Lisp, why would Parrot even need to
   > know?  S04 seems to require a great deal of bookkeeping for unhandled
   > exceptions, but would that necessarily impact Lisp handlers?

   It's just a little hack, no big deal.  Imagine this scenario:

     1. Parrot has exceptions
     2. Parrot requires handlers to mark exceptions handled with a "caught"
        [now "handled"] opcode
     3. Parrot has dynamic-wind

   Given:

     (handler-case (signal condition)
        (printer-on-fire () YOUR_FORM_HERE))

   Your CL compiler would replace YOUR_FORM_HERE with the equivalent of this,
   written in pidgin Scheme . . .

Impressive.  This is close to what I had in mind for the general case
when I said "I could install the equivalent of an UNDO block around the
Lisp code ..." above.  It looks like you're beginning to think like a
Lisp implementor.  (Are you scared yet?)

   But your implementation is really for this use of HANDLER-BIND:

     (handler-bind ((printer-on-fire #'(lambda (cond) YOUR_FORM_HERE)))
       (signal condition))

(Please bear with me here, I'm trying to draw parallels between CL and
Perl 6 error semantics.)  Typically, HANDLER-CASE is implemented in
terms of HANDLER-BIND, and creates a handler for PRINTER-ON-FIRE errors
that does a nonlocal transfer-of-control to the dynamic context of the
HANDLER-CASE.  (This is easier, in that code emitted by the compiler
knows that it's doing a nonlocal exit and can emit a C<handled> op
directly.)  The YOUR_FORM_HERE body [1] therefore runs in the original
HANDLER-BIND contenxt, not the error-signalling context.

   However, I notice that S04 doesn't explicitly specify the dynamic
environment for anything evaluated in a CATCH block.  (Indeed, it seems
to use the terms "handler" and "CATCH block" interchangeably.)  Would
the CATCH block still be in scope as a handler while it was executing?
This seems problematic, so I am hoping it's an oversight.  If so, then
that would make my life easier.  A key aspect of both HANDLER-CASE and
HANDLER-BIND is that none of the handlers they establish are in scope
when those handlers are invoked.  That way, if a badly-written handler
should be prone to (re)igniting printers, you don't get looping.

   But if you really do want CATCH blocks to be in effect when run, then
I have two ideas for PIR-level APIs for changing this default:

   1.  Implement "catch-out-of-own-scope" by default and let CATCH
blocks re-establish themselves when they execute, e.g. by doing a
C<push_eh_self> in the preamble; or

   2.  Store the list of active handlers in a global variable so that
PIR handler code can rebind them dynamically.

   I suspect that the lexical nature of the 'handled' flag may not match the
   interpreter-wide-dynamic nature of the signal stack, leading to incorrect
   results with nested signals.  But with that caveat, I think this would work.

You might also get odd results if the context was re-entered and
re-exited while some other error was being signalled.  For instance,
what would happen the second time your dynamic-wind cleanup block is
run?  (This couldn't happen in vanilla CL, but might in Parrot if the
handler called something else that took a continuation.)

   However, this ought to be fixable by having the C<handled>
instruction mention the exception that it wants to mark as caught.

                                        -- Bob

[1]  The spec calls them "error clauses"; see
     
http://www.lispworks.com/documentation/HyperSpec/Body/m_hand_1.htm#handler-case

Reply via email to