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


6.9.11 Clean–up thunks and the dynamic environment

As R6RS states:

Some operations described in the report acquire information in addition to their explicit arguments from the dynamic environment. For example, call/cc accesses an implicit context established by dynamic-wind, and the raise procedure accesses the current exception handler.

the typical example of values from the dynamic environment is parameters, which indeed are implemented on top of dynamic-wind (see iklib parameters). When using the unwind–protection mechanism:

(with-unwind-protection ?unwind-handler ?thunk)

the procedure ?unwind-handler is called in the dynamic environment of the use of with-unwind-protection.

For example, when escaping from ?thunk with return:

(import (vicare)
  (only (vicare checks)
        with-result
        add-result))

(define parm
  (make-parameter #f))

(with-result
  (parametrise ((parm 'outer-parm))
    (returnable
      (parametrise ((parm 'inner-parm))
        (with-unwind-protection
            (lambda (why)
              (add-result 'cleanup-in)
              (add-result (parm))
              (add-result 'cleanup-out))
          (lambda ()
            (add-result 'thunk-in)
            (add-result (parm))
            (return 2)
            (add-result 'thunk-out)
            1))))))
⇒ (2 (thunk-in inner-parm
       cleanup-in inner-parm cleanup-out))

we see that, even though return reinstates the continuation of returnable: ?unwind-handler gathers the parameter value from inside the use of returnable.

Even more descriptive is the case of raising an exception from ?thunk and catching it with guard:

(import (vicare)
  (only (vicare checks)
        with-result
        add-result))

(define parm
  (make-parameter #f))

(with-result
  (parametrise ((parm 'outer-parm))
    (guard (E ((begin
                 (add-result 'guard-test-in)
                 (add-result (parm))
                 (add-result 'guard-test-out)
                 #t)
               (add-result 'guard-expr-in)
               (add-result (parm))
               (add-result 'guard-expr-out)
               E))
      (parametrise ((parm 'inner-parm))
        (with-unwind-protection
            (lambda (why)
              (add-result 'cleanup-in)
              (add-result (parm))
              (add-result 'cleanup-out))
          (lambda ()
            (add-result 'thunk-in)
            (add-result (parm))
            (raise 2)
            (add-result 'thunk-out)
            1))))))
⇒ (2 (thunk-in inner-parm
       guard-test-in outer-parm guard-test-out
       cleanup-in inner-parm cleanup-out
       guard-expr-in outer-parm guard-expr-out))

both ?thunk and ?unwind-handler gather the inner value, while the test and expression of the guard clause gather the outer value, even though the execution order is intermixed.

Changing the environment inside ?thunk does not affect ?unwind-handler:

(import (vicare)
  (only (vicare checks)
        with-result
        add-result))

(define parm
  (make-parameter #f))

(with-result
  (parametrise ((parm 'outer-parm))
    (with-unwind-protection
        (lambda (why)
          (add-result 'cleanup-in)
          (add-result (parm))
          (add-result 'cleanup-out))
      (lambda ()
        (parametrise ((parm 'inner-parm))
          (add-result 'thunk-in)
          (add-result (parm))
          (add-result 'thunk-out)
          1)))))
⇒ (1 (thunk-in inner-parm thunk-out
       cleanup-in outer-parm cleanup-out))

(with-result
  (returnable
    (parametrise ((parm 'outer-parm))
      (with-unwind-protection
          (lambda (why)
            (add-result 'cleanup-in)
            (add-result (parm))
            (add-result 'cleanup-out))
        (lambda ()
          (parametrise ((parm 'inner-parm))
            (add-result 'thunk-in)
            (add-result (parm))
            (return 2)
            (add-result 'thunk-out)
            1))))))
⇒ (2 (thunk-in inner-parm
       cleanup-in outer-parm cleanup-out))

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