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/cc
accesses an implicit context established bydynamic-wind
, and theraise
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: iklib unwind-protect problems, Previous: iklib unwind-protect reenter, Up: iklib unwind-protect [Index]