我写了一个scheme interpreter in scala,它确实有效,但我仍然无法弄清楚它是如何在子程序之间切换的。 例如:
(call/cc
(lambda (k)
(k 1)
(display 2)))
我认为应该执行显示程序,但它没有。
在java中,它只是这样的东西:
public class Test {
static void call_cc(Consumer<Consumer> k,Consumer current){
k.accept(current);
}
public static void main(String[] args){
call_cc(consumer -> {
consumer.accept(1);
System.out.println(2);
},System.out::print);
}
}
那么我的观点是什么问题?
答案 0 :(得分:2)
call/cc
将程序重写为继续传递样式。我已经稍微更改了代码以显示结果并且之后有一个额外的代码,以便您可以了解它,这是我的修改:
(display (call/cc
(lambda (k)
(k 1)
(display 2))))
(display "finished")
在CPS中call/cc
只不过是:
(define (call/cc& f continuation)
(define (exit value actual-continuation)
(continuation value))
(f exit continuation)
退出函数在使用时会得到一个表示CPS中其余程序的闭包,但它的主要功能是使用它自己的连续而不是提供的连续。
我定义了display
的CPS版本和最终延续函数halt
; CPS version of display
(define (display& s k)
(display s)
(k 'undefined))
; The final continuation
; We make the REPL get the result and it display it
(define halt values)
现在重写代码。 CPS类型将代码更改为在每个步骤中仅计算一件事的步骤过程,而在Scheme中,评估的顺序取决于此形式的实现,订单将非常清楚地显示。请注意,它永远不会返回,只是在尾部位置调用continuation:
; CPS version of the code
(call/cc&
(lambda (exit continuation)
(exit 1
(lambda (unused)
(display& 2 continuation))))
(lambda (value)
(display& value
(lambda (unused)
(display& "finished" halt)))))
现在,如果你逐步完成这一点,很明显为什么它永远不会显示&#34; 2&#34;。