我是方案编程的新手,并且一直在尝试了解具有电流延续调用的程序的控制流。更具体地说,我想知道何时调用对任何延续的调用,控制权转移到何处以及之后会发生什么。如果考虑以下提到的程序进行解释,那将非常有帮助。
(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)
我得到新值;Value: 2
a
。等等...
我知道当我这样做时(define a (amb)
在语句(set! amb-exit (lambda () (f1 'exit)))
中调用延续f1
,它将控制权转移回第一个内部call/cc
,并且f1
延续返回exit
。
我无法理解的是为什么;Value: a
;Value: 1
而不是f1
返回的值exit
? 当这部分(f1 'exit)
被执行时,控制权返回到第一个内部调用/抄送,放弃它之后的任何内容(在本例中(m 1)
)。 因此,这部分(m 1)
永远不应该被调用,因为第一个内部延续,即f1
甚至在命中(m 1)
之前就exit
返回。
任何关于计划当前延续的有用意见也将不胜感激。
注意:使用 MIT/GNU 方案
不,当您这样做(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 'exit)
的f1
延续,后者返回(call/cc (lambda (f1) ...))
窗体中的值'exit
。此值将被丢弃,控件将传递到具有类似效果的(call/cc (lambda (f2) ...))
窗体中。