了解无限延续
假设我有以下代码(类似 C 的语法):
void foo(int arg) { ... } int bar() { ... // call with continuation ... } foo ( bar() ) // after foo invocation
1) 函数 foo
调用函数 bar
,该函数一直运行,直到到达带有 call 的行继续
。
2) 在这一行创建了一个延续
函数。它代表 bar
和 foo
的其余部分。 continuation
函数作为参数传递给call with continuation
函数。
3) call with continuation
函数对参数执行任何它想要的操作(例如,它可能只存储在全局变量中)并返回。
4) 一旦 call with continuation
返回,我们立即跳转到“after foo incall”的行,而 bar
和 foo
的其余部分则不会被执行。
5) 为了继续执行 bar
和 foo
我们应该显式调用 continuation
函数(在 (2) 中创建并可能存储在 ( 3))。一旦调用了 Contination 函数,执行就会在调用 Continue 后立即继续。
正确吗?我是否遗漏了有关无限延续的内容?
Suppose, I have the following code (in C-like syntax):
void foo(int arg) { ... } int bar() { ... // call with continuation ... } foo ( bar() ) // after foo invocation
1) Function foo
invokes function bar
, which is running until it reaches the line with call with continuation
.
2) At this line a continuation
function is created. It represents the rest of bar
and foo
. The continuation
function is passed as an argument to call with continuation
function.
3) The call with continuation
function does whatever it wants with the argument (e.g. it may just store in a global variable) and returns.
4) Once the call with continuation
returns we immediately jump to the line with "after foo invocation" and the rest of bar
and foo
are not executed.
5) In order to continue execution of bar
and foo
we should explicitly invoke the continuation
function (created in (2) and probably stored in (3)). Once the continuation
function is invoked the execution continues immediately after the call with continuation
.
Is it correct? Am I missing something about undelimited continuations?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不会。通常,当您调用
continuation
时,而不是当您调用call/cc
时,不定界延续(例如使用Scheme 的call/cc
创建)会跳转。 (又名call-with-current-continuation
)。因此,充实您的示例:
执行开始。我们输入
bar
(我们还没有输入foo
;当我们完成bar
时我们会输入)。当我们在
bar
中调用call/cc
时,“程序上下文”会变成一个称为 Continuation 的对象。此时,程序上下文包含“完成执行bar
,然后对结果调用foo
,然后执行foo
之后的操作”调用”。延续被传递给作为call/cc
参数给出的函数,在上面的示例中它是handler
。handler
对延续执行一些操作。我们假设它将其存储在全局变量中。然后它返回到call/cc
调用之后的位置,仍然在bar
内部。假设我们此时打印一些内容。然后
bar
完成,我们调用foo
,它就完成了。如果我们现在在
savedk
中应用延续,控制会跳回bar
并将程序上下文恢复为“完成执行bar
”,然后对结果调用foo
,然后执行foo
调用之后的操作”。所以我们打印了另一行。事实上,如果我们不清除savedk
变量或测试其他状态,如果调用“执行foo
调用后发生的任何事情”,我们可能会遇到无限循环再次savedk
!No. Typically, undelimited continuations (eg created with Scheme's
call/cc
) jump when you invoke thecontinuation
, not when you callcall/cc
(akacall-with-current-continuation
).So, fleshing out your example:
Execution starts. We enter
bar
(we haven't enteredfoo
yet; we'll do that when we get done withbar
).When we hit the call to
call/cc
inbar
, the "program context" is turned into an object called a continuation. At this point, the program context consists of "finish executingbar
, then callfoo
on the result, and then do whatever comes after thefoo
invocation". The continuation is passed to the function given as an argument tocall/cc
, which ishandler
in my example above.handler
does something with the continuation. Let's assume it stores it in a global variable. Then it returns to the point right after thecall/cc
call, still inside ofbar
.Let's say we print something out at this point. Then
bar
finishes and we callfoo
, and it finishes.If we now apply the continuation in
savedk
, control jumps back intobar
and restores the program context to "finish executingbar
, then callfoo
on the result, and then do whatever comes after thefoo
invocation". So we get another line printed. In fact, if we don't clear thesavedk
variable or test some other state, we might get an infinite loop if "do whatever comes after thefoo
invocation" is callsavedk
again!