如何在Racket

时间:2015-10-26 20:36:27

标签: racket continuations callcc

我正在研究Racket中的call/cc Continuations by example:例外,时间旅行搜索,生成器,线程和协同程序 1

该文件提到最有利的API是通过提供程序call/cclambda (cc) (cc cc)派生的。我理解这个特定的call/cc调用会将当前的continuation first-class对象返回给主程序。

在下面的示例中,论文调用了所有这些(right-now)

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

我没有看到cc中有什么特别的价值,所以我尝试将其作为(cc ())(cc (lambda () ()))或{偶然{的函数启动{1}}和(cc "whatever")。没有任何快乐:显然,延续只需要 应用程序自身才能开始运行。

为什么?什么样的例子清楚地说明了通过(cc)运行cc的独特性?

1 个答案:

答案 0 :(得分:2)

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

(current-continuation)的延续是

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

请拨打此续约c0

current-continuation的定义是:

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

所以call/cc(lambda (cc) (cc cc))作为参数调用c0

  ((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)))的值是延续。如果我们想要掌握它,我们需要返回它,我们通过将其传递给延续来实现。即(cc something)会返回一些内容,因为我们想要获得延续,我们会使用(cc cc)