【发布时间】: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