raise should not change continuation
Marc Feeley 12 Aug 2002 12:09 UTC
> (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
situations.
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:
(call-with-current-continuation
(lambda (return)
(with-exception-handler
(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.
Marc