这个Scheme列表迭代器如何使用call-with-current-continuation?
我正在尝试阅读此代码:
(define list-iter
(lambda (a-list)
(define iter
(lambda ()
(call-with-current-continuation control-state)))
(define control-state
(lambda (return)
(for-each
(lambda (element)
(set! return (call-with-current-continuation
(lambda (resume-here)
(set! control-state resume-here)
(return element)))))
a-list)
(return 'list-ended)))
iter))
任何人都可以解释 call-with-current-continuation
在此示例中如何工作吗?
谢谢
I'm trying to read this code:
(define list-iter
(lambda (a-list)
(define iter
(lambda ()
(call-with-current-continuation control-state)))
(define control-state
(lambda (return)
(for-each
(lambda (element)
(set! return (call-with-current-continuation
(lambda (resume-here)
(set! control-state resume-here)
(return element)))))
a-list)
(return 'list-ended)))
iter))
Can anyone explain how call-with-current-continuation
works in this example?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
call-with-concurrent-continuation
(简称为call/cc
)的本质是在程序执行期间获取检查点或延续的能力。然后,您可以通过像函数一样应用它们来返回到这些检查点。下面是一个不使用延续的简单示例:
如果不使用延续,则很难分辨出区别。以下是我们实际使用它的一些地方:
当调用延续时,控制流跳回由
call/cc
获取延续的位置。将call/cc
表达式视为一个洞,由传递给k
的任何内容填充。list-iter
是call/cc
的更复杂的使用,并且可能是一个很难开始使用它的地方。首先,这是一个示例用法:这是所发生情况的草图:
list-iter
返回一个没有参数i
的过程。i
被调用时,我们立即获取一个延续并将其传递给control-state
。当调用绑定到return
的延续时,我们将立即返回到调用i
的人。control-state
的定义,这意味着我们将在下次步骤 2 出现时从那里继续。control-state
之后,我们将列表的当前元素传递回return
延续,产生列表的一个元素。'list-ending
调用return
延续。由于control-state
未更新,因此每次调用i
时,它都会返回'list-ending
。正如我所说,这是
call/cc
的相当复杂的使用,但我希望这足以完成这个示例。对于延续的更温和的介绍,我建议选择经验丰富的策划者 。The essence of
call-with-concurrent-continuation
, orcall/cc
for short, is the ability to grab checkpoints, or continuations, during the execution of a program. Then, you can go back to those checkpoints by applying them like functions.Here's a simple example where the continuation isn't used:
If you don't use the continuation, it's hard to tell the difference. Here's a few where we actually use it:
When the continuation is invoked, control flow jumps back to where the continuation was grabbed by
call/cc
. Think of thecall/cc
expression as a hole that gets filled by whatever gets passed tok
.list-iter
is a substantially more complex use ofcall/cc
, and might be a difficult place to begin using it. First, here's an example usage:Here's a sketch of what's happening:
list-iter
returns a procedure of no argumentsi
.i
is invoked, we grab a continuation immediately and pass it tocontrol-state
. When that continuation, bound toreturn
, is invoked, we'll immediately return to whoever invokedi
.control-state
with that new continuation, meaning that we'll resume from there the next time step 2 comes along.control-state
for the next time through, we pass the current element of the list back to thereturn
continuation, yielding an element of the list.i
is invoked again, repeat from step 2 until thefor-each
has done its work for the whole list.return
continuation with'list-ended
. Sincecontrol-state
isn't updated, it will keep returning'list-ended
every timei
is invoked.As I said, this is a fairly complex use of
call/cc
, but I hope this is enough to get through this example. For a gentler introduction to continuations, I'd recommend picking up The Seasoned Schemer.基本上,它采用函数
f
作为参数,并将f
应用于程序的当前上下文/状态。来自维基百科:
(定义(f返回)
(返回2)
3)
(display (f (lambda (x) x))) ;显示 3
(display (call-with-current-continuation f)) ;显示 2
因此,基本上,当在没有 current-continuation (cc) 的情况下调用 f 时,该函数将应用于 2,然后返回 3。当使用 current-continuation 时,该参数将应用于 2,这会强制程序跳转到当前延续被调用的位置,并因此返回 2。它可用于生成返回,或暂停执行流程。
如果您了解 C,请这样想:在 C 中,您可以获取指向函数的指针。你还有一个回报机制。假设返回值采用与函数采用相同类型的参数。假设您可以获取其地址并将该地址存储在变量中或将其作为参数传递,并允许函数为您返回。它可以用来模仿 throw/catch,或者作为协程的机制。
Basically it takes a function
f
as its parameter, and appliesf
to the current context/state of the program.From wikipedia:
(define (f return)
(return 2)
3)
(display (f (lambda (x) x))) ; displays 3
(display (call-with-current-continuation f)) ; displays 2
So basically when f is called without current-continuation (cc), the function is applied to 2, and then returns 3. When using current-continuation, the parameter is applied to 2, which forces the program to jump to the point where the current-continuation was called, and thus returns 2. It can be used to generate returns, or to suspend execution flow.
If you know C, think about it like this: in C, you can take a pointer to a function. You also have a return mechanism. Suppose the return took a parameter of the same type the function takes. Suppose you could take its address and store that address in a variable or pass it as a parameter, and allow functions to return for you. It can be used to mimic throw/catch, or as a mechanism for coroutines.
这本质上是:
希望它更容易理解。
This is essentially:
Hope it is easier to understand.