具有当前调用连续性的Scheme程序中的控制流

时间:2018-10-28 17:45:45

标签: scheme control-flow continuations callcc

我是Scheme编程的新手,并且一直在尝试了解其中具有“带当前调用”功能的程序的控制流。更具体地说,我想知道何时调用任何延续的调用,控件在哪里转移以及此后会发生什么。如果考虑使用以下提到的程序进行解释,将非常有帮助。

(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)时,会在语句f1中调用延续(set! amb-exit (lambda () (f1 'exit))),它将控制权转移回第一内部call/cc和{{1 }}继续返回f1

我无法理解的是为什么exit;Value: a而不是;Value: 1返回的值exit? 一旦执行了该部分f1,控制就会返回到第一个内部调用/ cc,并放弃其后的任何内容(在这种情况下为(f1 'exit))。 因此,永远不要调用(m 1)这部分,因为即使在命中(m 1)之前,第一个内部延续,即f1都随exit返回。

在Scheme中有关当前通话的任何有用评论也将不胜感激。

注意:使用MIT / GNU方案

1 个答案:

答案 0 :(得分:1)

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

否,(set! amb-exit (lambda () (f1 'exit)))amb-exit设置为lambda函数,然后控件传递到(m 1),后者会调用延续 m 。从1中的(amb)返回(define a (amb)),从而将a设置为1

稍后您调用(back)时,它会调用(amb-exit),这时会调用f1的{​​{1}}延续,并从{{ 1}}表单。该值将被丢弃,控制权将以(f1 'exit)的形式传递,具有相似的效果。