这是延续传球风格吗?

问题描述 投票:0回答:1

如果函数

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)
scheme lisp racket
1个回答
4
投票

以延续传递风格编写的许多代码并不是严格延续传递风格,因为有些调用不会将其结果传递给延续。即便如此,您编写的代码可能不会被归类为 CPS,甚至不会被归类为半 CPS。延续传递风格的要点在于,函数不是从函数返回一些结果,而是采用一个称为延续的附加参数,并使用“结果”调用该函数。例如,对列表元素求和的 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,因为某些功能,即 carcdr+ 不是 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,它现在大概被定义为函数。传递函数与一流函数一起使用,但这并不意味着它是连续传递风格。

© www.soinside.com 2019 - 2024. All rights reserved.