我是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方案
答案 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)
的形式传递,具有相似的效果。