Next: dynamic environment parms, Up: dynamic environment [Index]
The dynamic environment is a subset of the state of a vicare
process that is maintained with the in–guard and out–guard thunks of
dynamic-wind
.
Let’s consider the following program prelude:
#!vicare (import (vicare) (only (vicare checks) with-result add-result)) (define var) (define (step id) (add-result (list id var)) (++ var)) (define-syntax dotimes (syntax-rules () ((_ ?count . ?body) (do ((i 0 (+ 1 i))) ((= i ?count)) . ?body)) ))
we can call the function step
to access and mutate the current
value of the variable var
; dotimes
is a simple macro
that evaluates a body a number of times. For example we can do:
(define (doit id init) (set! var init) (dotimes 5 (step id))) (with-result (doit 'single 0) 1) ⇒ (1 ((single 0) (single 1) (single 2) (single 3) (single 4)))
this program does not define a dynamic environment.
Now, with the same prelude, let’s consider the following code making use of coroutines:
(define (doit id init) (define local-var) (coroutine (lambda () (dynamic-wind (lambda () (set! var local-var)) (lambda () (set! var init) (dotimes 5 (step id) (yield))) (lambda () (set! local-var var)))))) (with-result (doit 'one 0) (doit 'two 10) (finish-coroutines) 1) ⇒ (1 ((one 0) (two 10) (one 1) (two 11) (one 2) (two 12) (one 3) (two 13) (one 4) (two 14)))
this program defines a dynamic environment:
var
the local value
local-var
:
(lambda () (set! var local-var))
local-var
the global value
var
:
(lambda () (set! local-var var))
this way the function step
called by the body thunk of
dynamic-wind
accesses and mutates a variable var
that
holds a value “private” to the coroutine.
The standard with-exception-handler
uses the same mechanism to
install in the dynamic environment the current exception handler. The
following program shows how with-exception-handler
transparently
installs as handler a closure for each coroutine:
#!vicare (import (vicare) (only (vicare checks) with-result add-result)) (define-syntax dotimes (syntax-rules () ((_ ?count . ?body) (do ((i 0 (+ 1 i))) ((= i ?count)) . ?body)) )) (define (doit name init) (define X init) (coroutine (lambda () (with-exception-handler (lambda (E) (++ X)) (lambda () (dotimes 5 (add-result (list name (raise-continuable (void)))) (yield))))))) (with-result (doit 'one 0) (doit 'two 10) (finish-coroutines) 1) ⇒ (1 ((one 1) (two 11) (one 2) (two 12) (one 3) (two 13) (one 4) (two 14) (one 5) (two 15)))
Next: dynamic environment parms, Up: dynamic environment [Index]