[racket] Delimited continuations and parameters
On 05/14/2012 04:26 PM, Asumu Takikawa wrote:
> Hi all,
>
> Here is a code snippet that uses both delimited continuations and
> parameters (translated from the paper "Delimited Dynamic Binding"[1]):
>
> #lang racket
>
> (require racket/control)
>
> (define p (make-parameter 0))
> (define r (make-parameter 0))
>
> ((λ (f)
> (parameterize ([p 2])
> (parameterize ([r 20])
> (f 0))))
> (parameterize ([p 1])
> (reset
> (parameterize ([r 10])
> ((λ (x) (+ (p) (r)))
> (shift f f))))))
>
> If you run this, it produces 11. The authors of [1] argue that it should
> return 12, namely because it follows the principle that "the dynamic
> bindings in scope are those in the context".
>
> That makes some sense, considering that when you eventually get to the
> call (f 0) in the first lambda, your context looks like
>
> (parameterize ([p 2])
> (parameterize ([r 20])
> (f 0)))
>
> where f = (λ (y)
> (parameterize ([r 10])
> ((λ (x) (+ (p) (r)))
> y)))
>
> according to shift/reset semantics. From this context, p = 2, r = 10
> could make sense.
>
> That said, I don't really have an intuition for what semantics for
> dynamic binding& delimited control is useful. Is there a pragmatic
> reason for why Racket's parameters and delimited control interact in
> this fashion?
Racket contexts don't store individual parameter values, they store
entire *parameterizations* (which effectively contain the values of all
parameters). So f captures the parameterization {p=1, r=10}. When f is
called, it restores the entire parameterization, overriding the existing
mapping {p=2, r=20} at the call site.
Jay's "mark parameter" library (at unstable/markparam) provides
semantics that are probably closer to what you expect. (Except, IIRC,
not inherited across threads as parameters are.)
Ryan