如何解释Scheme中的(call/cc call/cc)表达式行为?
关于call/cc的续体传递疑问
用call/cc解释CPS程序的基础示例
我熟悉用call/cc以直接风格解释CPS程序,比如下面的例子:
(define (f return) (return 2) 3) (f (lambda (x) x)) => 3 (call/cc f) => 2
调用(f (lambda (x) x))时,return只是普通函数,执行完(return 2)后继续返回3;而用call/cc调用时,return被绑定为当前续体,调用它会直接跳出函数,返回2。
(call/cc call/cc)的等价行为
我也清楚(call/cc call/cc)的特殊行为:((call/cc call/cc) x)等价于(x x),比如:
((call/cc call/cc) display) => #<procedure #2 display>
实际运行中这等价于调用(display display),输出过程对象本身。
续体传递的核心疑问
外层的call/cc会将代表当前续体的过程(记为★)传给作为参数的内层call/cc,这个外层续体对应的执行上下文是(★ display)——也就是拿到值后直接把它作为整个表达式的结果返回。
但这里的关键问题是:内层的call/cc并非在它的源码位置被调用,而是作为高阶函数的参数(一个值)被外层call/cc调用的,此时它会向外层的续体过程传递什么续体?
如果错误地假设内层call/cc是在源码位置求值,我会得到这样的推导过程:
((¹call/cc ²call/cc) display) (²call/cc ¹(★ display)) (²((¹call/cc ★) display) display) ((¹call/cc display) display) (display ¹(★ display))
这个推导结果和实际运行的(display display)完全不符,说明我的续体假设存在错误。
内容的提问来源于stack exchange,提问作者Aly
相关产品推荐
相关产品推荐

