# [plt-scheme] inheriting dynamic extent

Doug Orleans <dougo at place.org> writes:
>* For list-related administrative tasks:
*>* http://list.cs.brown.edu/mailman/listinfo/plt-scheme
*>*
*>* The dynamic extent of a procedure is the time when processing is
*>* "inside" a procedure, but it doesn't include the dynamic extent of
*>* procedures created during this time. For example:
*>*
*>* ((let ((x 1))
*>* (dynamic-wind (lambda () (set! x 2))
*>* (lambda () (lambda () x))
*>* (lambda () (set! x 1)))))
*>* ; => 1
*>*
*>* Or equivalently:
*>*
*>* ((let ((x 1))
*>* (fluid-let ((x 2))
*>* (lambda () x))))
*>* ; => 1
*>*
*>* Is there some way to allow procedures to "inherit" dynamic extent?
*>* (Or some trick to simulate this?) In other words, is there a way to
*>* make something analogous to this example that returns 2 instead of 1?
*
Oy. Richard Kelsey had a pair of procedures that did stuff like this
in his Scheme Workshop 2003 paper on threads. I think it was:
;; Return a value that represents the current dynamic context.
(define (capture-context)
(call/cc (lambda (k1)
;; Don't miss the double parens!
((call/cc (lambda (k2) (k1 k2)))))))
;; Call THUNK in dynamic context CTX.
(define (call-in-context ctx thunk)
(call/cc (lambda (k)
(ctx (lambda ()
(k (thunk)))))))
So your example would become:
((let ((x 1))
(dynamic-wind (lambda () (set! x 2))
(lambda ()
(let ((ctx (capture-context)))
(lambda () (call-in-context ctx
(lambda () x)))))
(lambda () (set! x 1)))))
which does evaluate to 2.
(I must have thought that was *really cool* to still remember it now.
With the FrTime and Picbit presentations, that was an awesome
workshop.)