Next: iklib unwind-protect problems, Previous: iklib unwind-protect reenter, Up: iklib unwind-protect [Index]
As R6RS states:
Some operations described in the report acquire information in addition to their explicit arguments from the dynamic environment. For example,
call/ccaccesses an implicit context established bydynamic-wind, and theraiseprocedure 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: iklib unwind-protect problems, Previous: iklib unwind-protect reenter, Up: iklib unwind-protect [Index]