[plt-scheme] inheriting dynamic extent

From: Jim Blandy (jimb at redhat.com)
Date: Sat Apr 2 02:48:52 EST 2005

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.)



Posted on the users mailing list.