Next: , Up: exceptions   [Contents][Index]


4.1 Exceptions handling

This section describes MMCK Exceptional Conditions’s exception–handling and exception–raising constructs provided by the (mmck exceptional-conditions) library.

Exception handlers are one–argument procedures that determine the action the program takes when an exceptional situation is signalled. The system implicitly maintains a current exception handler as part of the dynamic environment of the program.

The program raises an exception by invoking the current exception handler, passing it an object encapsulating information about the exception. Any procedure accepting one argument may serve as an exception handler and any object may be used to represent an exception.

When a program begins its execution, the predefined exception handler:

When the handler returns:

Function: with-exception-handler handler thunk

The argument handler must be a procedure and should accept one argument. The argument thunk must be a procedure that accepts zero arguments. The with-exception-handler procedure returns the results of invoking thunk. handler is installed as the current exception handler for the dynamic extent (as determined by dynamic-wind) of the invocation of thunk.

Syntax: guard (?variable ?cond-clause1 ?cond-clause2 …) ?body0 ?body
Auxiliary Syntax: =>
Auxiliary Syntax: else

Each ?cond-clause is as in the specification of the standard syntax cond. ‘=>’ and ‘else’ are matched as symbols.

Evaluating a guard form evaluates the ?body forms with an exception handler that binds the raised object to ?variable and within the scope of that binding evaluates the clauses as if they were the clauses of a cond expression. That implicit cond expression is evaluated with the continuation and dynamic environment of the guard form. If every ?cond-clause’s ?test evaluates to #f and there is no else clause, then raise-continuable is invoked on the raised object within the dynamic environment of the original call to raise or raise-continuable except that the current exception handler is that of the guard expression.

Function: raise obj

Raise a non–continuable exception by invoking the current exception handler on obj.

The handler is called with a continuation whose dynamic environment is that of the call to raise, except that the current exception handler is the one that was in place when the handler being called was installed. So if the handler itself raises an exception: that exception will be handled by the upper level handler; no infinite loop will happen by invoking the same handler again and again.

(call-with-current-continuation
    (lambda (escape)
      (with-exception-handler
          (lambda (A)
            (escape (cons 'A A)))
        (lambda ()
          (with-exception-handler
              (lambda (B)
                (raise (cons 'B B)))
            (lambda ()
              (with-exception-handler
                  (lambda (C)
                    (raise (cons 'C C)))
                (lambda ()
                  (raise 123)))))))))
⇒ (A B C . 123)

If the handler returns: a non–continuable exception with condition type &non-continuable is raised in the same dynamic environment as the handler.

(define C
  (call-with-current-continuation
      (lambda (escape)
        (with-exception-handler
            escape
          (lambda ()
            (with-exception-handler
                ;;This handler returns!
                (lambda (obj) obj)
              (lambda ()
                (raise 123))))))))

(condition? C)                  ⇒ #t
(serious-condition? C)          ⇒ #t
(violation? C)                  ⇒ #t
(non-continuable-violation? C)  ⇒ #t
(condition-irritants C)         ⇒ (123)
Function: raise-continuable obj

Raise a continuable exception by invoking the current exception handler on obj. The handler is called with a continuation that is equivalent to the continuation of the call to raise-continuable, with these two exceptions:

  1. The current exception handler is the one that was in place when the handler being called was installed. So if the handler itself raises an exception: that exception will be handled by the upper level handler; no infinite loop will happen by invoking the same handler again and again.
    (call-with-current-continuation
        (lambda (escape)
          (with-exception-handler
              (lambda (A)
                (escape (cons 'A A)))
            (lambda ()
              (with-exception-handler
                  (lambda (B)
                    (raise (cons 'B B)))
                (lambda ()
                  (with-exception-handler
                      (lambda (C)
                        (raise (cons 'C C)))
                    (lambda ()
                      (raise 123)))))))))
    ⇒ (A B C . 123)
    
  2. If the handler being called returns, then it will again become the current exception handler and the values it returns become the values returned by the call to raise-continuable.
    (with-exception-handler
        ;;This handler returns 2 values!
        (lambda (obj)
          (values 'obj obj))
      (lambda ()
        (raise-continuable 123)))
    ⇒ obj 123
    

Next: , Up: exceptions   [Contents][Index]

This document describes version 0.1.0-devel.1 of MMCK Exceptional Conditions.