【发布时间】:2019-12-17 21:24:23
【问题描述】:
我看到了一个来自 The Scheme Programming Language 的例子,它可以转换
(letrec ([f (lambda (x) (cons 'a x))]
[g (lambda (x) (cons 'b (f x)))]
[h (lambda (x) (g (cons 'c x)))])
(cons 'd (h '()))) (d b a c)
进入 CPS
(letrec ([f (lambda (x k) (k (cons 'a x)))]
[g (lambda (x k)
(f x (lambda (v) (k (cons 'b v)))))]
[h (lambda (x k) (g (cons 'c x) k))])
(h '() (lambda (v) (cons 'd v))))
除了添加一个额外的参数来将延续传递给函数之外,该函数是否需要进行尾调用?该示例显示所有转换后的函数都进行尾调用,但 CPS 的文本和维基百科没有明确说明这样的要求。
如果一个函数不需要进行尾调用,我们是否可以将延续应用于函数体中要返回的值,即如果要返回的原始值是expr,那么我们可以重写吗它作为(k expr) 其中k 是延续参数,而不进一步将其转换为尾调用?
比如g和h可以改写成
g (lambda (x k) (k (cons 'b (f x (lambda (x) x)))))
h (lambda (x k) (k (g (cons 'c x) (lambda (x) x))))
?如果不可接受,我想可能还有其他方法可以不写它们进行尾调用?
【问题讨论】:
-
你重写的
g和h仍然在尾部调用k。
标签: scheme continuations continuation-passing