Scheme:嵌套调用/cc如何为协同路由工作?

Scheme:嵌套调用/cc如何为协同路由工作?,scheme,coroutine,callcc,continuation,Scheme,Coroutine,Callcc,Continuation,我正在查看以下来自的协同程序示例: 多余的工作: ;; notionally displays a clock (define (superfluous-computation do-other-stuff) (let loop () (for-each (lambda (graphic) (display graphic) (newline) (set

我正在查看以下来自的协同程序示例:

多余的工作:

 ;; notionally displays a clock 
 (define (superfluous-computation do-other-stuff) 
    (let loop () 
      (for-each (lambda (graphic) 
                  (display graphic) 
                  (newline) 
                  (set! do-other-stuff (call/cc do-other-stuff))) 
                '("Straight up." "Quarter after." "Half past."  "Quarter til.")) ; point B
      (loop))) 


(hefty-computation superfluous-computation) 
对于call/cc的第一个用法,上下文应该是什么?当我说上下文时,我的意思是,由于callcc的跳转,我们应该“返回”到哪里

据我所知,第一次调用call/cc时,do other stuff本质上变成了一个执行多余计算代码的过程,然后跳到集合后面的点!(A点)。第二次,它将围绕“跳转到点A并执行上下文,或点A后面的任何代码”来包装其“跳转到点B”行为。这是正确的吗

如果设置为!事实上发生了。或者是布景!此代码是否需要运行


对正在发生的事情进行可视化表示确实会有所帮助。

调用/cc的上下文是调用
call/cc
的地方。您几乎可以想到一个
call/cc
,比如
goto
,它将代码跳回到您之前的位置,并用返回值替换
(call/cc whatever)

call/cc
基本上是这样说的,“让我们去做这个函数,把它交给别人,直接跳回到这里,忘掉它在做什么。”

好的,当我第一次尝试理解
call/cc
时,我发现这段代码非常混乱,所以让我们看一个简化的协同程序示例:

(define r1
  (lambda (cont)
    (display "I'm in r1!")
    (newline)
    (r1 (call/cc cont))))

(define r2
  (lambda (cont2)
    (display "I'm in r2!")
    (newline)
    (r2 (call/cc cont2))))
好的,这与代码的概念完全相同。但这要简单得多

在这种情况下,如果我们调用
(r1r2)
,这将打印

I'm in r1
I'm in r2
I'm in r1
I'm in r2    
I'm in r1
I'm in r2    
I'm in r1
I'm in r2
...
为什么??因为
r1
首先将r2作为
cont
接收,所以它向我们宣布它在r1中。然后它在自身上递归,结果是
(call/cc cont)
aka
(call/cc r2)

好的,那么这个的回报是什么?那么
(call/cc r2)
将开始执行r2,并宣布它在r2中,然后以
(call/cc cont2)
的结果在自身上递归。好的,那么什么是
cont2
cont2
是之前在
r1
中的表达式的延续。所以当我们在这里调用它时,我们返回一个延续到我们当前所在的位置。然后,我们忘记了在r2中所做的一切,跳回执行r1

现在在
r1
中重复此操作。我们宣布内容,然后跳回r2中之前的位置,使用前面的表达式,
(call/cc cont2)
返回我们在
r1
中的继续,然后继续我们的快乐无限循环

回到你的代码
在您的代码中,这个概念是完全相同的。事实上,当你停下来思考时,
多余的计算
几乎与上述函数相同。那么
设置是怎么回事s?在这段代码中,他们所做的就是将
do other work
的值更改为最新的延续。就这样。在我的示例中,我使用了递归。在本例中,他们使用
set

当你说“cont2是r1之前表达式的延续”时,你是说cont2是一个跳回行
r1(call/cc-cont)
的过程,除了
(call/cc-cont)
被一个跳转到r2将要递归的过程所取代?在你真正完成
r1(call/cont)
的结果之前,我很难理解
call/cc cont
的最终结果是什么。说
(cont2 val)
类似于说跳回
r1(call/cc cont)
并用val替换
(call/cc cont)
当我说replace时,我的意思是,
(call/cc cont)
的计算结果为val。如果它有帮助,您可以将其视为一个替换,因此,如果我在执行call/cc cont2时理解正确,我们将跳转到(r1 val),其中val是r2的延续。然后我们递归到r1,cont变成“跳到r2将递归调用自己的地方”?非常感谢你迄今为止的帮助,我真的很感激。我花了一整天的时间试图弄清楚这些东西是如何工作的。是的,这是一个普遍的想法,它也帮助我用两个手指跟随,一个是执行的内容,一个是下一个继续跳转的位置
I'm in r1
I'm in r2
I'm in r1
I'm in r2    
I'm in r1
I'm in r2    
I'm in r1
I'm in r2
...