首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个Scheme列表迭代器是如何使用call-with-current-continuation的?

这个Scheme列表迭代器是如何使用call-with-current-continuation的?
EN

Stack Overflow用户
提问于 2011-04-12 10:25:58
回答 3查看 1K关注 0票数 4

我正在试着读这段代码:

代码语言:javascript
复制
(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是如何工作的吗?

谢谢

EN

回答 3

Stack Overflow用户

发布于 2011-04-12 11:17:28

call-with-concurrent-continuation或简称call/cc的本质是在程序执行期间获取检查点或延续的能力。然后,您可以通过像函数一样应用它们来返回到这些检查点。

下面是一个不使用延续的简单示例:

代码语言:javascript
复制
> (call/cc (lambda (k) (+ 2 3)))
5

如果不使用延续,就很难区分。下面是我们实际使用它的几个地方:

代码语言:javascript
复制
> (call/cc (lambda (k) (+ 2 (k 3))))
3
> (+ 4 (call/cc (lambda (k) (+ 2 3))))
9
> (+ 4 (call/cc (lambda (k) (+ 2 (k 3)))))
7

当继续被调用时,控制流跳回到被call/cc抓取的延续的位置。可以将call/cc表达式看作是一个空洞,可以通过传递给k的任何内容来填充它。

list-itercall/cc的一个非常复杂的用法,可能很难开始使用它。首先,这是一个示例用法:

代码语言:javascript
复制
> (define i (list-iter '(a b c)))
> (i)
a
> (i)
b
> (i)
c
> (i)
list-ended
> (i)
list-ended

以下是正在发生的事情的草图:

  1. list-iter返回一个没有参数的过程,当调用i.
  2. When i时,我们立即获取一个延续并将其传递给control-state。当绑定到return的continuation被调用时,我们将立即返回给调用了i.
  3. For列表中每个元素的人,我们将获取一个新的continuation,并用新的continuation覆盖control-state的定义,这意味着我们将在下一次执行步骤2时从那里继续。
  4. 在为下一次设置control-state之后,我们将列表的当前元素传递回return continuation,从而产生列表的一个元素。
  5. 当再次调用i时,从步骤2开始重复,直到for-each完成了整个列表的工作。
  6. 使用'list-ended调用return延续。因为control-state没有更新,所以每次调用i时它都会一直返回'list-ended

正如我所说的,这是call/cc的一个相当复杂的用法,但我希望这足以完成这个示例。要对continuations进行更温和的介绍,我建议使用The Seasoned Schemer

票数 3
EN

Stack Overflow用户

发布于 2011-04-12 11:22:27

基本上,它接受函数f作为其参数,并将f应用于程序的当前上下文/状态。

来自维基百科:

(define (f return)

(return 2)

3)

(display (f (lambda (x) x))) ; displays 3

(display (call-with-current-continuation f)) ; displays 2

因此,基本上当f被调用而不使用current-continuation (cc)时,该函数被应用于2,然后返回3。当使用current-continuation时,该参数被应用于2,这强制程序跳到调用当前延续的点,从而返回2。它可用于生成返回,或用于暂停执行流。

如果你了解C语言,可以这样想:在C中,你可以带一个指向函数的指针。你也有一个返回机制。假设返回的参数类型与函数的类型相同。假设您可以获取它的地址并将其存储在一个变量中,或者将其作为参数传递,并允许函数为您返回。它可以用来模拟抛出/接球,或者作为协程的一种机制。

票数 0
EN

Stack Overflow用户

发布于 2015-06-27 23:37:15

这本质上是:

代码语言:javascript
复制
(define (consume)
  (write (call/cc control)))

(define (control ret)
   (set! ret (call/cc (lambda (resume)
                        (set! control resume)
                        (ret 1))))
   (set! ret (call/cc (lambda (resume)
                        (set! control resume)
                        (ret 2))))
   (set! ret (call/cc (lambda (resume)
                        (set! control resume)
                        (ret 3)))))

(consume)
(consume)
(consume)

希望它更容易理解。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5629727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档