Next: unwind problems, Previous: unwind reenter, Up: unwind [Contents][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. When using the unwind–protection mechanism:
(with-unwind-handler ?unwind-handler ?thunk)
the procedure ?unwind-handler is called in the dynamic environment of the use of
with-unwind-handler.
For example, when escaping from ?thunk with return:
(import (only (mmck checks)
with-result
add-result))
(define parm
(make-parameter #f))
(with-result
(parameterize ((parm 'outer-parm))
(returnable
(parameterize ((parm 'inner-parm))
(with-unwind-handler
(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 (only (mmck checks)
with-result
add-result))
(define parm
(make-parameter #f))
(with-result
(parameterize ((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))
(parameterize ((parm 'inner-parm))
(with-unwind-handler
(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 (only (mmck checks)
with-result
add-result))
(define parm
(make-parameter #f))
(with-result
(parameterize ((parm 'outer-parm))
(with-unwind-handler
(lambda (why)
(add-result 'cleanup-in)
(add-result (parm))
(add-result 'cleanup-out))
(lambda ()
(parameterize ((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
(parameterize ((parm 'outer-parm))
(with-unwind-handler
(lambda (why)
(add-result 'cleanup-in)
(add-result (parm))
(add-result 'cleanup-out))
(lambda ()
(parameterize ((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: unwind problems, Previous: unwind reenter, Up: unwind [Contents][Index]
This document describes version 0.1.0-devel.1 of MMCK Exceptional Conditions.