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


6.1 Introduction to the unwind–protection mechanism

The syntax with-unwind-handler implements the core mechanism. unwind-protect offers a syntax similar to the one of the Common Lisp macro with the same name. The former is meant to be used as follows:

(let ((port (open-output-file "file.ext")))
  (with-unwind-handler
      (lambda (why)
        (close-output-port port))
    (lambda ()
      (put-bytevector port '#ve(ascii "ciao")))))

and the latter as follows:

(let ((port (open-output-file "file.ext")))
  (unwind-protect
      (put-bytevector port '#ve(ascii "ciao"))
    (close-output-port port)))

first we allocate a resource (in this case the port); then we use it in the body forms; finally we release it in the clean–up forms.

When using the mechanism:

If the bodacious answer to both the decisions is “We trust”: we can nest at will uses of with-unwind-handler:

(define (outer)
  (with-unwind-handler
      (lambda (why)
        (outer-unwind-handler))
    (lambda ()
      (do-something-useful)
      (inner))))

(define (inner)
  (with-unwind-handler
      (lambda (why)
        (inner-unwind-handler))
    (lambda ()
      (do-some-other-useful-thing))))

(outer)

beware: unwind handlers are evaluated in the dynamic environment of the use of with-unwind-handler.

Otherwise, we must avoid error handlers to cause the execution flow to cross an unwind protection boundary; we can do it by using compensations and the standard guard syntax:

(define (outer)
  (push-compensation-thunk
    (lambda ()
      (outer-unwind-handler)))
  (do-something-useful)
  (inner))

(define (inner)
  (push-compensation-thunk
    (lambda ()
      (inner-unwind-handler)))
  (do-some-other-useful-thing))

(with-compensations
  (with-blocked-exceptions
    (lambda ()
      (guard (E ((type-one-error? E)
                 (handle E))
                (else
                 (do-something-dammit!!!)))
        (outer)))))

or by using the compensations and the try syntax defined by MMCK Exceptional Conditions:

(define (outer)
  (push-compensation-thunk
    (lambda ()
      (outer-unwind-handler)))
  (do-something-useful)
  (inner))

(define (inner)
  (push-compensation-thunk
    (lambda ()
      (inner-unwind-handler)))
  (do-some-other-useful-thing))

(with-compensations
  (with-blocked-exceptions
    (lambda ()
      (try
          (outer)
        (catch E
          ((&type-one)
           (handle E))
          (else
           (do-something-dammit!!!)))))))

beware: compensation handlers are evaluated in the dynamic environment of the use of with-compensations.


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

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