为什么延续没有用处?

时间:2012-07-05 07:20:03

标签: scheme racket continuations

请考虑以下代码:

(call-with-values
    (lambda ()
      (call/cc (lambda (k)
         (k k k))))
  (lambda (x y)
    (procedure-arity y)))

这里很明显,call/cc调用点的延续是右边的lambda,所以它的arity应该是2.但是,上面的返回值(在Racket中)取而代之的是(arity-at-least 0)

事实上,在Guile中运行类似的代码(用procedure-minimum-arity代替procedure-arity)表明延续也可以允许任意数量的参数,即使很明显不是这样。

那么,为什么呢?据我所知(如果我的理解是错误的,请纠正我),延续的优点非常简单:除了call-with-values的上下文之外它是1,在这种情况下,无论右手的是什么 - 边lambda是。 (如果它是case-lambda之类的话,授予可能会很复杂,但不会比直接调用(procedure-arity (case-lambda ...))更复杂。)

1 个答案:

答案 0 :(得分:2)

更简单的方法是:

(call-with-values
  (lambda () (error 'arity "~v" (procedure-arity (call/cc (λ (k) k)))))
  (lambda (x y) (procedure-arity y)))

甚至更简单:

(procedure-arity (call/cc (λ (x) x)))

对于你的问题 - 在第一种情况下很明显延续期望两个输入,但这样的情况并不常见。例如,它们通常是这样的例子,而“真实代码”将使用define-values或具有一些未知的延续,其中call/cc创建的延续可以具有不同的元素,具体取决于它们在。这意味着试图弄清楚这些罕见的情况已经没有多大意义了。

脚注:

;; nonsensical, but shows the point
(define (foo) (call/cc (λ (x) x)))
(define x (foo))
(define-values [y z] (foo))