[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

raise should not change continuation

This page is part of the web mail archives of SRFI 34 from before July 7th, 2015. The new archives for SRFI 34 contain all messages, not just those from before July 7th, 2015.

> (raise obj ) 
>   Invokes the current exception handler on obj . The handler is called
>   in the dynamic environment of the call to raise , except that the
>   current exception handler is that in place for the call to
>   with-exception-handler that installed the handler being called. The
>   handler's continuation is otherwise unspecified.

I'm sorry to say, but this definition is inconsistent with SRFI 18
because of this section in SRFI 18:

 Primitives and exceptions
   When one of the primitives defined in this SRFI raises an exception
   defined in this SRFI, the exception handler is called with the same
   continuation as the primitive (i.e. it is a tail call to the
   exception handler). This requirement avoids having to use
   call-with-current-continuation to get the same effect in some

In SRFI 18 the exception handler must be called with the same
continuation as "raise" (and consequently the same dynamic
environment and exception handler).

The "try" form is important because it implicitly brings the dynamic
environment (and exception handler) back to what it was at the time of
the "try".  "with-exception-handler" must be used with great care and
understanding of the Scheme implementation because it can lead to an
infinite recursion.  For example:

    (lambda (return)
        (lambda (exc)
          (write (list 'got 'exception exc))
          (return 'an-exception-was-raised)))
      (lambda ()
        (list 1 2 3))))

In a Scheme implementation that signals heap overflows by raising an
exception, the call (list 1 2 3) will cause the exception handler to be
called if the 3 element list can't be allocated, which will again call
the same exception handler when the expression (list 'got 'exception exc)
is evaluated, etc, etc.

Robust and portable code should only use the "try" form.