[plt-scheme] restart exception handling?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Jul 13 19:34:31 EDT 2008

At Sun, 13 Jul 2008 15:22:23 -0400, David Vanderson wrote:
> 
> Matthew Flatt wrote:
> > 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)))
> >                y)
> >      ...)
> > 
> > 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)
> >                             (esc
> >                              (lambda ()
> >                                (continuable-error 
> >                                 'mega-fun 
> > 			        "cannot include val in list: ~e"
> >                                 x)))))
> >                         y)
> >                (lambda () ...))))
> > 
> 
> Thanks very much for the explanations.
> 
> Is there a reason why each exception should be thrown in tail position 
> with respect to the function?  Is that the convention for continuable 
> exceptions?

My intent was to set up some reasonable continuation for the exception
handler (i.e., the continuation of the call to functions like
`raise-continuable-type-error').

As above, I imagined that the exception handler would continue by
supplying some result for the call to `mega-fun'. Another choice would
be

   (define (mega-fun x y z)
     (let ([x (if (not (integer? x))
                  (raise-continuable-type-error 'mega-fun "integer" x)
                  x)])
       (let ([y (if (not (list? y)) ....)])
         ....)))

in which case the exception handler could supply an alternate value for
the argument. The exception raiser and exception handler would have to
agree on some protocol.

> Could you please elaborate on why you couldn't (or shouldn't) just 
> replace "raise-type-error" with "raise-continuable-type-error"?

What continuation would an exception handler be able to resume in that
case?

Matthew



Posted on the users mailing list.