如何在 Racket 中开始捕获当前的延续

How to start captured current continuations in Racket

我正在按照论文的思路研究 call/cc Racket 示例的延续:异常、时间旅行搜索、生成器、线程和协程 1.

论文中提到最有利的API是从call/cc派生出来的,提供了一个过程lambda (cc) (cc cc)。我理解这个特定的 call/cc 调用 returns 当前继续 first-class 对象到主程序。

在下面的例子中,论文称所有这些为(right-now)

我看到的是,在同一个示例中,上述 call/cc 调用返回的 cc 对象总是 运行 之后将其应用于自身。这就是我不明白的。

我看不出 cc 的值有什么特别之处,所以我尝试用 (cc ())(cc (lambda () ())) 甚至 (cc "whatever")(cc)。没有任何乐趣:显然,延续只需要 that 应用程序来开始 运行.

这是为什么?什么是通过执行 (cc cc) 清楚地说明 运行ning 抄送的独特性的示例?

(let ((cc (current-continuation)))
  ...)

(current-continuation)的延续是

(lambda (_)
  (let ((cc _))
    ...)

将此延续称为 c0

current-continuation的定义是:

(define (current-continuation)
  (call/cc (lambda (cc) (cc cc))))

因此 call/ccc0 作为参数调用 (lambda (cc) (cc cc))

  ((lambda (cc) (cc cc)) c0)
= (c0 c0)

正在插入 c0 的值:

((lambda (_)
   (let ((cc _))
     ...)
 c0)

变成:

   (let ((cc c0))
     ...)

这意味着在 ... 内部,标识符 cc 现在绑定到值 c0

如果 (c0 42) 出现在 ...

我们得到:

   (c0 42)
= ((lamdba (_)
     (let ((cc _))
      ...)
   42)
= (let ((cc 42))
     ...)

现在 cc 绑定到值 42。

该示例使用 (procedure? cc)(future-value? cc) 来测试 cc 是否绑定到延续(如果 (procedure? cc) 为真)和/或另一个值(未来值在这里 42).

所以在:

(define (current-continuation)
  (call/cc (lambda (cc) (cc cc))))

传给(lambda (cc) (cc cc)))的值是延续。如果我们想要处理它,我们需要 return 它,我们通过将它传递给 continuation 来做到这一点。 IE。 (cc something) 会 return 一些东西,因为我们想要获得延续本身,所以我们使用 (cc cc).