【问题标题】:Is this continuation passing style?这是续传风格吗?
【发布时间】:2015-12-20 19:36:43
【问题描述】:

如果函数acc作为它的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】:

    很多以连续传递风格编写的代码严格来说不是连续传递风格;因为有些调用不会将其结果传递给延续。即使这样,您编写的代码也可能不符合半 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,现在大概定义为函数。传递函数与一等函数一起工作,但这并不能使其成为延续传递风格。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 2011-05-30
      • 2012-01-22
      相关资源
      最近更新 更多