Functional programming 方案:继续编译
我目前正在用OCaml为scheme的一个子集编写编译器,在理解如何使用continuations进行编译时遇到了困难。我发现了一些很好的资源,即: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))
- 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))))