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 ____________________ Racket Users list: http://lists.racket-lang.org/users

