raise

[procedure] raise obj

SRFI-18, SRFI-21, SRFI-34:

From SRFI-18:

Calls the current exception handler (see current-exception-handler with obj as the single argument.

From SRFI-34:

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.

Note: there is a subtle issue about with what dynamic environment the current exception handler is called: whether the current exception handler value is restored to the previous one, or it should be the same as where raise is called? The difference is visible when you do

  (with-exception-handler 
      (lambda (e) (current-exception-handler))
    (lambda () (raise #t)))

SRFI-34 is clear about it. raise calls the current exception handler with dynamic enviornment where (current-exception-handler) is restored, so the above expression returns the handler which is installed outside of with-exception-handler.

SRFI-18 is a bit ambiguous. It says nothing about dynamic envionment in the description of raise, but in 'Primitives and exceptions' section it says 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. If we think raise as a primitive, it shouldn't change the continuation where the current exception handler is called, and since the dynamic enviornment is a part of a continuation, the current exception handler should see itself as a current exception handler---i.e. above expression returns the procedure created by (lambda (e) (current-exception-handler)). However, SRFI-18 is confusing since it doesn't define what is primitive.

This difference surfaces when you do cascading raise:

  (with-exception-handler (lambda (e) (raise e)) (lambda () (raise #t)))

In SRFI-34, this exits from with-exception-handler form by invoking the exception handler defined outside of the form. In SRFI-18 model, if we think raise as a primitive, this form loops infinitely, since (raise e) calls (lambda (e) (raise e)) again.

See the discussion thread beginning with Marc Feeley's message.

The behavior is also ambiguous when you return from the exception handler. SRFI-34 explicitly says the continuation of the exception handler is undefined (except the alteration of the current exception handler).

raise is also in MzScheme, Gauche.

See also current-exception-handler, with-handlers