环境不是方案延续的一部分吗?
我已经用 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))
当评估 LET 时,我期望为 -3,但在调用 kont 时期望为 +3(因为我认为程序会记住突变之前 a 和 b 的绑定(bind)):
(let ... ) ; <-- evaluating the LET above
; prints "mutating"
=> -3
(kont 100)
=> -3
(kont 100)
=> -3
所以延续只影响控制,而不影响环境?既然如此,为什么说实现延续的方法之一是“复制堆栈”(绑定(bind)不在堆栈上吗?)
最佳答案
延续捕获绑定(bind)。但是,正如您猜测的那样,这些绑定(bind)是可变的。
这里的“复制堆栈”口号有点误导了您。虽然这是考虑 call/cc 的合理方式,但这并不是故事的全部。一方面,您真的不希望有一种语言功能暴露本地绑定(bind)是否是堆栈分配的。
相反,call/cc 是使用“程序上下文”的概念来定义的。为了更好地解决这个问题,您可能需要看看 Shriram Krishnamurthi 的(免费在线)教科书 PLAI ,或者参见(不是免费的,更深入的)书“Semantics Engineering with PLT Redex”。
顺便说一句;你的程序并没有真正检查你想要它检查的内容,因为你从未调用捕获的延续。我想你想写这样的东西:
#lang racket
(define kont #f)
(let ([a 3])
(let/cc k
(set! kont k)
(set! a 4))
(printf "~s\n" a))
(kont)
...这显示了与您上面提到的几乎相同的行为。
关于scheme - 环境不是延续的一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6001164/