【问题标题】:Is a function in CPS required to make a tail call?CPS 中的函数是否需要进行尾调用?
【发布时间】: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 是延续参数,而不进一步将其转换为尾调用?

比如gh可以改写成

g (lambda (x k) (k (cons 'b (f x (lambda (x) x)))))
h (lambda (x k) (k (g (cons 'c x) (lambda (x) x))))

?如果不可接受,我想可能还有其他方法可以不写它们进行尾调用?

【问题讨论】:

  • 你重写的gh 仍然在尾部调用k

标签: scheme continuations continuation-passing


【解决方案1】:

当将方案代码转换为连续传递样式时,每个过程调用都成为尾调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 2012-12-15
    • 2014-01-03
    • 1970-01-01
    • 2020-05-14
    相关资源
    最近更新 更多