Mic*_*ael 3 language-agnostic continuations programming-languages functional-programming
假设,我有以下代码(类似 C 的语法):
void foo(int arg) { ... }
内部酒吧(){
...
// 继续调用
...
}
foo ( bar() )
// 在 foo 调用之后
1) 函数foo调用 function bar,该函数一直运行直到到达带有 的行call with continuation。
2) 在这一行continuation创建了一个函数。它代表的休息bar和foo。该continuation函数作为参数传递给call with continuation函数。
3)call with continuation函数对参数做任何它想做的事情(例如,它可能只存储在一个全局变量中)并返回。
4) 一旦call with continuation返回,我们立即跳转到带有“after foo invocation”的那一行,其余的bar和foo不执行。
5)为了继续执行bar,并foo应明确地调用continuation函数(在(2创建),可能存储在(3))。一旦continuation调用该函数,则在 之后立即继续执行call with continuation。
这是正确的吗?我是否遗漏了有关无分隔延续的内容?
不。通常,未定界的延续(例如,用 Scheme 的 创建call/cc)在您调用 时跳转continuation,而不是在您调用call/cc(又名call-with-current-continuation)时。
所以,充实你的例子:
continuation savedk;
void foo(int arg) { ... }
int bar() {
...
call/cc(handler)
// after call/cc
println "after call/cc"
...
}
void handler(continuation k) {
savedk = k
}
foo ( bar() )
// after foo invocation
Run Code Online (Sandbox Code Playgroud)
执行开始。我们输入bar(我们还没有输入foo;我们会在完成后输入bar)。
当我们调用call/ccin 时bar,“程序上下文”变成了一个称为延续的对象。此时,程序上下文包括“完成执行bar,然后调用foo结果,然后执行foo调用之后的任何操作”。延续被传递给作为参数给定的函数call/cc,这handler在我上面的例子中。
handler对延续做了一些事情。让我们假设它将它存储在一个全局变量中。然后它在call/cc调用后立即返回到该点,仍然在bar.
假设我们此时打印了一些东西。然后bar完成,我们调用foo,它就完成了。
如果我们现在应用 in 中的延续savedk,控制会跳回bar并恢复程序上下文以“完成执行bar,然后调用foo结果,然后执行foo调用之后的任何操作”。所以我们打印了另一行。事实上,如果我们不清除savedk变量或测试其他状态,如果再次foo调用“调用后执行任何操作”,我们可能会遇到无限循环savedk!