这是延续传递风格吗?
Is this continuation passing style?
如果函数a
有cc
作为它的CPS函数,并且cc
调用a
,那么a
是continuation passing style吗?例如,
(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)
很多以延续传递风格编写的代码并不是严格延续传递风格;因为有些调用不会将其结果传递给延续。即便如此,您编写的代码可能不符合半 CPS 的条件。 continuation 传递样式的要点在于,函数不是从函数返回一些结果,而是采用一个额外的参数,称为 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,但是,因为某些功能,即 car、cdr,并且 + 不是 CPS;他们将结果返回给调用者,而不是用结果调用延续。
现在让我们看看您提供的代码:
(def a
(lambda (b c)
...
(a (cons (c (car b))) c)))
在Scheme中,会这样写
(define (a b c)
...
(a (cons (c (car b))) c))
对 cons 的调用有错误的参数数量,但除此之外,没有明确的延续函数调用。您在函数位置使用 c,因此您正在利用高阶函数,并且正在递归调用 a,但这显然不是延续传递风格。在你的第二个区块中:
(def cc
(lambda (d)
...
(fold a x y)
(fold a u v)
不太清楚您要完成的任务。 Fold 没有以 CPS 方式使用,您忽略了第一次调用 fold 的结果。这里没有任何东西看起来像 CPS 风格。最后一点,
(a '((1 2) 3) cc)
您正在使用文字列表和 cc 调用 a,它现在大概被定义为一个函数。传递函数与 first-class 函数 一起工作,但这并不能使其成为连续传递样式。
如果函数a
有cc
作为它的CPS函数,并且cc
调用a
,那么a
是continuation passing style吗?例如,
(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)
很多以延续传递风格编写的代码并不是严格延续传递风格;因为有些调用不会将其结果传递给延续。即便如此,您编写的代码可能不符合半 CPS 的条件。 continuation 传递样式的要点在于,函数不是从函数返回一些结果,而是采用一个额外的参数,称为 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,但是,因为某些功能,即 car、cdr,并且 + 不是 CPS;他们将结果返回给调用者,而不是用结果调用延续。
现在让我们看看您提供的代码:
(def a
(lambda (b c)
...
(a (cons (c (car b))) c)))
在Scheme中,会这样写
(define (a b c)
...
(a (cons (c (car b))) c))
对 cons 的调用有错误的参数数量,但除此之外,没有明确的延续函数调用。您在函数位置使用 c,因此您正在利用高阶函数,并且正在递归调用 a,但这显然不是延续传递风格。在你的第二个区块中:
(def cc
(lambda (d)
...
(fold a x y)
(fold a u v)
不太清楚您要完成的任务。 Fold 没有以 CPS 方式使用,您忽略了第一次调用 fold 的结果。这里没有任何东西看起来像 CPS 风格。最后一点,
(a '((1 2) 3) cc)
您正在使用文字列表和 cc 调用 a,它现在大概被定义为一个函数。传递函数与 first-class 函数 一起工作,但这并不能使其成为连续传递样式。