【问题标题】:Control flow in a Scheme program having call-with-current-continuation具有当前继续调用的 Scheme 程序中的控制流
【发布时间】:2019-04-01 17:33:36
【问题描述】:

我是 Scheme 编程的新手,我一直在尝试了解其中包含 call-with-current-continuation 的程序的控制流程。更具体地说,我想知道何时调用对任何延续的调用,控制权转移到哪里以及之后会发生什么。如果考虑下面提到的程序进行解释,那将非常有帮助。

(define call/cc call-with-current-continuation)

(define amb-exit '())

(define amb
 (lambda ()
    (call/cc
      (lambda (m)
       (call/cc
         (lambda (f1)
           (set! amb-exit (lambda () (f1 'exit)))
           (m 1)))
       (call/cc
         (lambda (f2)
           (set! amb-exit (lambda () (f2 'exit)))
           (m 2)))
       (call/cc
         (lambda (f3)
           (set! amb-exit (lambda () (f3 'exit)))
           (m 3)))))))

(define back (lambda () (amb-exit)))

现在,我尝试以 (define a (amb)) 的这种方式运行代码,然后我在终端中得到这样的值 ;Value: a。然后在终端中检查a 的值,它返回;Value: 1。然后我调用(back) 我得到a 新值;Value: 2。等等……

我知道当我执行(define a (amb) 时,在(set! amb-exit (lambda () (f1 'exit))) 语句中调用延续f1,它将控制权转移回第一个内部call/cc 并且f1 延续返回exit

我无法理解的是,为什么 ;Value: a;Value: 1 而不是 f1 返回的值 exit? 在执行这部分(f1 'exit) 的那一刻,控制返回到第一个内部调用/cc,放弃它之后的任何内容(在本例中为(m 1))。 所以,这部分(m 1) 永远不应该被调用,因为第一个内部延续,即f1 甚至在点击(m 1) 之前就返回了exit

任何关于 Scheme 中的 call-with-current-continuation 的有用 cmets 也将不胜感激。

注意:使用 MIT/GNU 方案

【问题讨论】:

  • 我已经解释了几次call/cc,但我相信this 是最简单的。理解call/cc需要一些时间,它确实有助于实现一个基本的方案编译器。

标签: scheme control-flow continuations callcc


【解决方案1】:

不,当您执行(define a (amb)) 时,不会调用延续f1,因为它位于lambda 的后面(即内部)。

不,(set! amb-exit (lambda () (f1 'exit)))amb-exit 设置为 lambda 函数,然后控制权传递给 (m 1),它确实调用了延续 m。它从(define a (amb)) 中的(amb) 返回1,从而将a 设置为1

当您稍后调用(back) 时,它会调用(amb-exit),此时会调用f1 延续,(f1 'exit)(call/cc (lambda (f1) ...)) 表单返回值'exit。该值被丢弃,控制权传递到(call/cc (lambda (f2) ...)) 表单,具有类似的效果。

【讨论】:

  • 感谢您的回答。只是为了澄清一下,每当控制到达像 (lambda () (f1 'exit)) 这样的点时,这是否意味着 lambda 函数在不执行其主体的情况下返回,并且稍后当使用它设置的任何变量调用此 lambda 时,然后lambda 函数的主体得到评估?
  • 是的,像往常一样,评估表单(set! amb-exit (lambda () (f1 'exit))) 意味着评估参数,即找到它的值。 (lambda () (f1 'exit)) 的值是一个 lambda 函数。并且仅在稍后调用该 lambda 函数时,才输入其主体并评估其形式。
猜你喜欢
  • 1970-01-01
  • 2016-08-27
  • 2012-11-03
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多