Next: , Up: iklib unwind-protect   [Index]


6.9.1 Introduction to the unwind–protection mechanism

The syntax with-unwind-handler implements the core mechanism; with-unwind-protection is an alias for it. 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:

#!vicare
(import (vicare))

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

and the latter as follows:

#!vicare
(import (vicare))

(let ((port (open-file-output-port "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-protection:

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

(define (inner)
  (with-unwind-protection
      (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-protection.

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 Vicare:

(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: iklib unwind-protect   [Index]