call/cc如何从两个子程序跳转

how does call/cc jump from two subrutine

我写了一个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);
    }
}

所以我的观点有什么问题?

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)

exit 函数在使用时会得到一个表示 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 中,评估的顺序取决于以这种形式实现的顺序,顺序将非常清楚地显示出来。请注意,它从不 returns,只是在尾部位置调用延续:

; 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)))))

现在,如果您逐步执行此操作,就会很明显为什么它从不显示“2”。