理解无限延续

时间:2011-05-20 10:13:25

标签: language-agnostic programming-languages functional-programming continuations

假设我有以下代码(使用类C语法):

void foo(int arg) { ... }

int bar() {
...
// call with continuation 
...
}

foo ( bar() )
// after foo invocation

1)函数foo调用函数bar,它一直运行,直到到达call with continuation的行。

2)在此行创建continuation函数。它代表barfoo的其余部分。 continuation函数作为参数传递给call with continuation函数。

3)call with continuation函数对参数做任何想做的事情(例如它可能只存储在一个全局变量中)并返回。

4)call with continuation返回后,我们立即跳转到“foo调用后”行,其余的barfoo都没有执行。

5)为了继续执行barfoo,我们应该显式调用continuation函数(在(2)中创建并可能存储在(3)中)。一旦调用了continuation函数,就会在call with continuation之后立即执行。

这是对的吗?我错过了关于无限延续的事情吗?

1 个答案:

答案 0 :(得分:4)

没有。通常,当您调用call/cc时,无限制的延续(例如,使用Scheme的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
  1. 执行开始。我们输入bar(我们尚未输入foo;当我们完成bar时,我们会这样做。

  2. 当我们在call/cc中点击bar时,“程序上下文”会变成一个称为延续的对象。此时,程序上下文包括“完成执行bar,然后对结果调用foo,然后执行foo调用之后的任何操作”。继续传递给作为call/cc的参数给出的函数,在我上面的示例中为handler

  3. handler对延续做了一些事情。我们假设它将它存储在全局变量中。然后它会在call/cc调用后立即返回到bar内部。

  4. 让我们说我们在这一点上打印出来的东西。然后bar结束,我们致电foo,然后结束。

  5. 如果我们现在在savedk中应用延续,控制会跳回bar并将程序上下文恢复为“完成执行bar”,然后调用foo在结果上,然后在foo调用之后执行任何操作。所以我们打印另一条线。实际上,如果我们不清除savedk变量或测试其他状态,如果“在foo调用后执行任何操作”再次调用savedk,我们可能会得到一个无限循环!