scheme - “continuation prompt?”到底是什么

标签 scheme racket continuations delimited-continuations

我正在尝试破译the documentation

call-with-continuation-prompt

Applies proc to the given args with the current continuation extended by a prompt. The prompt is tagged by prompt-tag, which must be a result from either default-continuation-prompt-tag (the default) or make-continuation-prompt-tag. The result of proc is the result of the call-with-continuation-prompt call.



我理解其中的部分内容:“将proc应用于具有当前延续的给定arg s”,然后从那里开始就是乱码。

连续被“扩展”甚至意味着什么?“提示”如何进行这种“扩展”?

最佳答案

从概念上讲,提示是什么?

Scheme通常具有延续性的概念,但是Racket用分隔的延续性的概念扩展了它。延续的想法是它可以捕获剩余的待评估计算。我不会尝试一般性地解释续集,因为这不在此问题的范围内。

但是,我将解释什么使分隔延续变得特别。通常,捕获延续将捕获整个计算,一直到最高层。这使得它们在实现复杂控制结构方面的使用相对受到限制,因为应用延续将完全释放程序执行的控制权。

使用定界的延续,您只能捕获延续的特定部分。实际捕获的评估部分由提示界定,该提示类似于沿当前连续性的标记,用于指定要捕获的连续性。

好的,但是那意味着什么呢?

与无界延续相比,没有真正看到界界延续的概念并不清楚。

标准(无界)延续

考虑以下示例代码。

(define *k* #f)

(sqrt
 (+ 1 2 3
    (call/cc
     (λ (k)
       (set! *k* k)
       0))))

该代码非常简单-它捕获了一个延续并将其存储到全局绑定(bind)*k*中。延续本身看起来像这样:
(sqrt (+ 1 2 3 _))

(其中_表示在调用延续时要填充的“孔”。)

应用这种延续将完全符合人们的预期。
> (*k* 3) ; evaluates (sqrt (+ 1 2 3 3))
3

这都是很普通的。那么定界延续带来了什么不同?

定界的延续

如果我们只想捕获*k*中的延续部分,该怎么办?例如,如果我们只想捕获这种延续怎么办?
(+ 1 2 3 _) ; the inner portion of the last continuation

我们可以通过建立延续提示来做到这一点,该提示会调整实际捕获的延续数量。
(sqrt
 (call-with-continuation-prompt
  (λ ()
    (+ 1 2 3
       (call/cc
        (λ (k)
          (set! *k* k)
          0))))))

现在,应用*k*给出内部结果:
> (*k* 3)
9

类比分隔连续

连续性可能是一个有点抽象的概念,因此,如果上面的代码示例不太清楚,请考虑此类比。

评估模型是一个堆栈-每个函数调用都会将一个新的框架推送到堆栈上,然后从函数返回将该框架弹出堆栈。我们可以将 call 堆栈可视化为一叠卡片。

正常情况下,当捕获到延续时,它将捕获当前帧及其下方的所有帧,如下图所示。

未捕获以蓝色表示的顶层。它实际上是带分隔符的系统中的默认提示。

但是,安装新的提示会在框架之间创建一种透明的分隔线,这会影响将哪些框架作为延续的一部分进行捕获。

该分隔符界定了延续的范围。

附录:提示标签和延续障碍

这是定界连续性的基础,但是还有其他方法可以控制连续性,从而为连续性系统提供更大的功能(并保护其免受恶意代码的侵害),这些都是快速标记和持续性障碍。

提示标记的想法本质上是标记给定提示的“标签”。使用上面的卡类比,可以为每个透明的分隔物分配一个标签。然后,当您捕获延续时,即使在其他提示之间夹有其他标签的情况下,也可以指定从头一直捕获到该特定标签。

延续障碍是一种安全措施。就像提示一样,它们可以可视化为位于调用堆栈元素之间的“分隔符”,而不是用作标记来控制捕获堆栈的多少,它们可以用作防护,以防止继续跳转通过“调用”屏障。

有关此的更多详细信息,请考虑阅读the section in the Racket reference on continuation barriers。摘录如下:

Specifically, a continuation can be replaced by another only when the replacement does not introduce any continuation barriers. It may remove continuation barriers only through jumps to continuations that are a tail of the current continuation. A continuation barrier thus prevents “downward jumps” into a continuation that is protected by a barrier.

关于scheme - “continuation prompt?”到底是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29838344/

相关文章:

recursion - 有没有更有效的方法来编写这个递归过程?

hash - 方案高阶函数

scheme - 在 Racket 中使用 peano 数进行划分

haskell - 从 Continuation monad 中的 IO monad 转义

windows - 我的 Racket 方案命令行在 Windows Powershell 中无法正常工作,我做错了什么

scheme - 这个scheme/script-fu/gimp代码有什么错误?

scheme - Racket 中 eval 允许的标识符的重复定义?

recursion - 降低 Racket 的功能?

scheme - 编码一个什么都不做的延续

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