环境不是延续的一部分?

时间:2011-05-14 10:17:00

标签: scheme continuations

环境不是计划延续的一部分吗?

我用Chicken,Gauche,Racket和Gambit进行了测试,它们的行为类似:

(define kont #f)

(let ((a 1)
      (b 2))
  (call-with-current-continuation
   (lambda (k)
     (set! kont k)
     (display 'mutating)
     (newline)
     (set! a -1)
     (set! b -2)))
  (display (+ a b))
  (newline))

我希望-3在评估LET时,但在调用kont时为+3(因为我认为程序会记住突变前a和b的绑定):

(let ... ) ; <-- evaluating the LET above
; prints "mutating"
=> -3
(kont 100)
=> -3
(kont 100)
=> -3

所以延续只影响控制,而不影响环境?在这种情况下,为什么说实现continuation的方法之一是“复制堆栈”(绑定不在堆栈上?)

2 个答案:

答案 0 :(得分:3)

延续捕获绑定。但是,正如你猜测的那样,这些绑定是可变的。

你在这里被“复制堆栈”的口号误导了。虽然这是考虑呼叫/ cc的合理方式,但并不是整个故事。首先,你真的不想要一个暴露本地绑定是否是堆栈分配的语言功能。

相反,call / cc是使用“program contexts”的概念定义的。要想对此有所了解,您可能需要查看Shriram Krishnamurthi(免费在线)教科书PLAI,或者(非免费,更深入)的书“使用PLT Redex的语义工程” ”。

撇开;你的程序并没有真正检查你想要检查的内容,因为你从未调用过捕获的延续。我想你想写这样的东西:

#lang racket

(define kont #f)

(let ([a 3])

  (let/cc k
    (set! kont k)
    (set! a 4))
  (printf "~s\n" a))

(kont)

...显示了与上面提到的几乎相同的行为。

答案 1 :(得分:1)

您可以使用set!更改环境中a和b的值。所以a和b在连续环境中是-1和-2。您无法展开副作用。在你的继续中,a,b和kont之间没有区别。