了解无限延续

发布于 2024-11-08 11:15:53 字数 828 浏览 1 评论 0原文

假设我有以下代码(类似 C 的语法):

void foo(int arg) { ... }

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

foo ( bar() )
// after foo invocation

1) 函数 foo 调用函数 bar,该函数一直运行,直到到达带有 call 的行继续

2) 在这一行创建了一个延续函数。它代表 barfoo 的其余部分。 continuation 函数作为参数传递给call with continuation 函数。

3) call with continuation 函数对参数执行任何它想要的操作(例如,它可能只存储在全局变量中)并返回。

4) 一旦 call with continuation 返回,我们立即跳转到“after foo incall”的行,而 barfoo 的其余部分则不会被执行。

5) 为了继续执行 barfoo 我们应该显式调用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放手` 2024-11-15 11:15:53

不会。通常,当您调用 continuation 时,而不是当您调用 call/cc 时,不定界延续(例如使用Scheme 的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. 当我们在 bar 中调用 call/cc 时,“程序上下文”会变成一个称为 Continuation 的对象。此时,程序上下文包含“完成执行 bar,然后对结果调用 foo,然后执行 foo 之后的操作”调用”。延续被传递给作为 call/cc 参数给出的函数,在上面的示例中它是 handler

  3. handler 对延续执行一些操作。我们假设它将其存储在全局变量中。然后它返回到 call/cc 调用之后的位置,仍然在 bar 内部。

  4. 假设我们此时打印一些内容。然后 bar 完成,我们调用 foo,它就完成了。

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

No. Typically, undelimited continuations (eg created with Scheme's call/cc) jump when you invoke the continuation, not when you call call/cc (aka call-with-current-continuation).

So, fleshing out your example:

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. Execution starts. We enter bar (we haven't entered foo yet; we'll do that when we get done with bar).

  2. When we hit the call to call/cc in bar, the "program context" is turned into an object called a continuation. At this point, the program context consists of "finish executing bar, then call foo on the result, and then do whatever comes after the foo invocation". The continuation is passed to the function given as an argument to call/cc, which is handler in my example above.

  3. handler does something with the continuation. Let's assume it stores it in a global variable. Then it returns to the point right after the call/cc call, still inside of bar.

  4. Let's say we print something out at this point. Then bar finishes and we call foo, and it finishes.

  5. If we now apply the continuation in savedk, control jumps back into bar and restores the program context to "finish executing bar, then call foo on the result, and then do whatever comes after the foo invocation". So we get another line printed. In fact, if we don't clear the savedk variable or test some other state, we might get an infinite loop if "do whatever comes after the foo invocation" is call savedk again!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文