我正在研究Racket中的call/cc
Continuations by example:例外,时间旅行搜索,生成器,线程和协同程序 1。
该文件提到最有利的API是通过提供程序call/cc
从lambda (cc) (cc cc)
派生的。我理解这个特定的call/cc
调用会将当前的continuation first-class对象返回给主程序。
在下面的示例中,论文调用了所有这些(right-now)
。
我看到的是,在同一个示例中,上述cc
调用返回的call/cc
对象总是通过将其应用于自身来运行。这是我不明白的。
我没有看到cc
中有什么特别的价值,所以我尝试将其作为(cc ())
或(cc (lambda () ()))
或{偶然{的函数启动{1}}和(cc "whatever")
。没有任何快乐:显然,延续只需要 应用程序自身才能开始运行。
为什么?什么样的例子清楚地说明了通过(cc)
运行cc的独特性?
答案 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)
。