这是继续传递风格吗?

时间:2015-09-23 13:01:56

标签: scheme lisp racket

如果函数a具有cc作为其CPS函数,而cc调用a,则a是否继续传递样式?例如,

(def a
    (lambda (b c)
        ...
        (a (cons (c (car b))) c))) 

(def cc
     (lambda (d)
          ...
          (fold a x y)
          (fold a u v)
...

(a '((1 2) 3) cc)

1 个答案:

答案 0 :(得分:3)

许多用continuation-passing-style编写的代码不是严格 continuation-passing-style;因为有些调用没有将结果传递给延续。即便如此,您编写的代码可能也不符合半CPS的条件。继续传递样式的要点是,该函数不是从函数返回一些结果,而是采用另一个参数,称为continuation,并使用“result”调用该函数。例如,用于对列表元素求和的CPS函数可能如下所示:

(define (sum-list lst k)
  (if (null? lst)
    ;; if the list is empty, then call the continuation
    ;; with the sum of the empty list, i.e., zero.
    (k 0)
    ;; Otherwise, compute the sum of the rest of the list,
    ;; but with a different continuation that will take
    ;; the sum of the rest of the list, add the first 
    ;; element of the list, and call the original continuation,
    ;; k, with that combined sum.
    (sum-list (cdr lst)
              (lambda (sum)
                (k (+ (car lst) sum))))))

这不是严格 CPS,因为一些功能,即汽车 cdr + 不是CPS;他们将结果返回给调用者,而不是继续调用结果。

现在让我们来看看你提供的代码:

(def a
    (lambda (b c)
        ...
        (a (cons (c (car b))) c))) 

在Scheme中,这将写成

(define (a b c)
   ...
   (a (cons (c (car b))) c))

缺点的调用具有错误的参数数量,但除此之外,没有明确调用延续函数。你在函数位置使用 c ,所以你正在利用高阶函数,并且你正在递归调用 a ,但它不是什么这显然是继续传递风格。在你的第二个街区:

(def cc
     (lambda (d)
          ...
          (fold a x y)
          (fold a u v)

你想要完成的事情并不是很清楚。 折叠未以CPS方式使用,而您忽略了第一次折叠调用的结果。这里没有什么看起来像CPS风格。在最后一点,

(a '((1 2) 3) cc)

您使用文字列表和 cc 调用 a ,现在可能将其定义为函数。传递函数是使用第一类函数,但这不会使它成为连续传递样式。