[plt-scheme] restart exception handling?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Jul 13 08:43:33 EDT 2008

At Fri, 11 Jul 2008 14:18:21 -0700, YC wrote:
> On Fri, Jul 11, 2008 at 6:21 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> > Not in general. Aside from `exn:break', built-in exceptions are raised
> > in a non-continuable way.
> >
> Just curious - what are the main reasons behind the exception design to make
> them non-continuable by default?

Exceptions are typically raised (both in the core and in Scheme code)
with code like this:

  (define (mega-fun x y z)
    (unless (integer? x)
      (raise-type-error 'mega-fun "integer" x))
    (unless (list? y)
      (raise-type-error 'mega-fun "list" y))
    (for-each (lambda (e)
                (when (equal? e x)
                  (error 'mega-fun "cannot include val in list: ~e" x)))

To make those exceptions continuable, the function has to be written in
a different way, and often that's a pain:

  (define (mega-fun x y z)
    (if (not (integer? x))
       (raise-continuable-type-error 'mega-fun "integer" x))
       (if (not (list? y))
           (raise-continuable-type-error 'mega-fun "list" y))
           ((let/ec esc
              (for-each (lambda (e)
                          (when (equal? e x)
                             (lambda ()
			        "cannot include val in list: ~e"
               (lambda () ...))))

That goes for all the exceptions raised by the run-time system, too.

For that reason, `error', `raise-type-error', etc. should not raise
continuable exceptions. The part of the run-time system that raises
`exn:fail:contract:variable' could be written in a continuable way, of
course; but for that exception and all the others, it hasn't seemed
useful enough to bother. (At one point, it seemed useful enough to make
`exn:break' continuable, but I don't know whether that capability is
actually used anywhere.)

There's another question of whether you want to use the same mechanism
for continuable exceptions as non-continuable exceptions. That issue is
discussed in a separate thread on this list:


> (is contination
> the basis for flow controls as scheme generally advertises?)

I think you're asking about MzScheme's implementation of first-class
continuations, and whether the same representation is used for all
kinds of control flow in MzScheme. No, it isn't.

> > That's not quite the problem. It's more that the exception handler is
> > required to escape, and also that the exception for an undefined
> > variable doesn't provide a place to escape back to.
> >
> So what are the contination-marks used for?

The original comment was about *barriers*, not *marks*.

> I thought they can be used for
> invoking continuations. 

Marks are for attaching information to parts of a continuation.
Barriers prevent certain "jumps" from one continuation to another.

> The related concepts (prompts, continuation,
> escape, etc) continues to escape me even with the manual.  If there are some
> links or pointers on how they are all related and used - it's much
> appreciated.

Probably you've seen the relatively new guide chapter:


And maybe this set of pictures in conference-paper form:


And the paper's bibliography points to many other sources for some
things. That's what we have so far.


Posted on the users mailing list.