WRT exception handling, I think the lisp condition/handler model is a good
starting point.  It's simple enough to explain and use, and static models
can easily be implemented in terms of it.

But I really don't like one thing about the CL handler model: it conflates
non-local transfers of control with "this exception is now handled".  So (1)
every continuation invocation has to check to see whether an exception is
live so it can be marked dead, which complicates what should be as efficient
as possible, and (2) creative condition handlers can't use continuations as
an implementation tool.

But I see a way out; see below.

On Thu, Jun 15, 2006 at 12:03:56AM -0400, Bob Rogers wrote:
>    3.  FWIW, the Scheme dynamic-wind feature requires an action to be
> invoked when re-entering the context as well as leaving it.  But this is
> probably not relevant, as a real Scheme implementation would probably
> not need Parrot continuations or actions in any case.

Huh, that's odd, coming from you.  Having just spent the better part of my
evening wrapping my head around call/cc and dynamic-wind, I'm about to
modify pdd23 to replace push_handler with:

    $P0 = newclosure sub_to_call_when_entering_scope
    $P1 = newclosure sub_to_call_when_leaving_scope
    $P2 = newclosure sub_to_call_when_scope_is_finally_inaccessible
    push_dynscope $P0, $P1, $P2   # [*]
    ...
    pop_dynscope                  # [**]

So, having chosen Scheme as a good model for scope and continuation
handling, wouldn't a Scheme compiler want to take advantage of that?

And getting back to exceptions, I'm seeing something that's pretty much like
the CL model, where the 'push_eh' opcode takes a _closure_, and the list of
handlers is its own array in the interpreter, not in the generic control
stack, and which is called at 'throw' time in the dynamic context of the
'throw'.  For conventional static languages like Perl 6 (:-)), the handler
would pretty much report that the exception was handled (e.g. with a
'caught' opcode) and then invoke a continuation which had been taken by the
Perl 6 compiler to point to the 'catch' code.

(Given the dynscope feature, it would be possible to do all of this without
Parrot's help, which is a good sign for the design of dynscope; but I think
Parrot should go ahead and help out to make it run quickly.)

Now how would a CL compiler use this?  I ask, and also answer:

If dynamic-wind is implemented (see below), it seems to me that a CL
compiler could wrap each handler in a dynamic scope in such a way as to trap
a non-local transfer distinctly from a return, and in the former case,
automatically invoke the hypothetical Parrot "caught" opcode.  So CL users
get full CL semantics, and everybody gets a faster continuation.invoke()
operation.

It seems so obvious that I'd suggest that's how it works, except for some
reason I can't fathom, CL doesn't support continuations...?

>    On the other hand, since static exception blocks haven't been implemented
>    yet, it's not too late to ditch the whole change as a bad job, if that's
>    the right decision for Lisp and other languages.  Lispers are people too.  
> :-)
> 
> You mean -+<{gasp}>+- I can come out of my closet now?

Join us out here, in the *bigger* closet!

I'm glad you kept CL and Scheme in view.  After today, modeling
continuations and condition handling without reference to Scheme and Lisp
seems as foolish as modeling text searching without reference to Perl.

[*] I think a version of push_dynscope that accepts three sub labels
    directly could also be OK, but since often one or more of them will be
    NULL, it's probably a waste.

[**] The opposite of "push" is "pop", dammit!  Not "clear".  Sheesh.
-- 
Chip Salzenberg <[EMAIL PROTECTED]>

Reply via email to