Functional programming 方案:继续编译

Functional programming 方案:继续编译,functional-programming,compiler-construction,scheme,Functional Programming,Compiler Construction,Scheme,我目前正在用OCaml为scheme的一个子集编写编译器,在理解如何使用continuations进行编译时遇到了困难。我发现了一些很好的资源,即: cmsu编译器课程的cps幻灯片: 另一门cs课程的解释: Matt可能会在a-normal表单和cps上发布帖子: 和 使用异常论文中介绍的异常转换,我现在得到了函数调用绑定到变量或返回的代码 例如: (define (fib n) (if (<= n 1) n (+ (fib (- n 1))

我目前正在用OCaml为scheme的一个子集编写编译器,在理解如何使用continuations进行编译时遇到了困难。我发现了一些很好的资源,即:

  • cmsu编译器课程的cps幻灯片:
  • 另一门cs课程的解释:
  • Matt可能会在a-normal表单和cps上发布帖子:

使用异常论文中介绍的异常转换,我现在得到了函数调用绑定到变量或返回的代码

例如:

(define (fib n)
  (if (<= n 1)
      n
      (+ (fib (- n 1)) 
         (fib (- n 2)))))
当使用这种脱胶剂时,如何:

(+ 2 (call/cc (lambda (k) (k 2))))
在MIT方案返回4中,因为当前的延续可能类似于显示

这是正确的吗

(定义(fib n k)

(让([c(使用continuations编译的思想的本质是,您希望对传递给每个函数的参数的求值进行排序,并且在求值该参数后,将其值发送给传递的continuation

您在CPS表单中重写代码所用的语言必须是尾部递归的,否则它将堆栈空帧,后面只有一个返回。如果实现语言不强制尾部递归,您需要应用更复杂的方法来获得CPS代码的非增长堆栈

注意,如果您这样做,您还需要更改原语的签名。原语也将被传递一个延续,但它们会立即返回传递的延续中的答案,它们不会创建其他延续


关于理解如何使用continuations编译的最佳参考仍然是,您不需要更多。

CPS没有堆栈,因为函数调用变成了goto@ceving。您应该阅读您引用的文章,了解如何在不使用堆栈框架的情况下实现它。
(define (fib n k)
  (let ([c (<= n 1)])
    (if c
        (k n)
        (let ([n-1 (- n 1)])
          (fib n-1 
            (lambda (v0) 
              (let ([n-2 (- n 2)]) 
                (fib n-2
                  (lambda (v1) 
                    (k (+ v0 v1))))))))))
(call/cc) => ((lambda (k f) (f k k)))
(+ 2 (call/cc (lambda (k) (k 2))))