scheme - 环境不是延续的一部分?

标签 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))

当评估 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/

相关文章:

lambda - 方案: "mcar: contract violation, expected: mpair, given: #<procedure:..."

list - 递归地将列表的第一个元素附加到列表的其余部分

optimization - 延续+尾递归技巧是否真的用堆栈空间交换堆空间?

functional-programming - 延续单子(monad)?

scheme - MIT 方案中的分类器和变压器是什么?

scheme - 检查数字是否出现在数字列表中

interpreter - 持续传递风格与积极修剪调用堆栈?

scheme - 求人为的示例代码: continuations!

haskell - 延续作为有意义的理解

emacs - 如何使用Emacs运行方案?