考虑以下代码:
(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
)表明,延续显然也允许任何数量的参数,即使显然不是这种情况。那么,为什么呢?据我所知(如果我的理解是错误的,请纠正我),延续的Arity非常简单:除
call-with-values
的上下文外为1,它在这种情况下与右侧lambda的Arity无关。 (当然,如果是case-lambda
之类的话,可能会很复杂,但没有比直接调用(procedure-arity (case-lambda ...))
时复杂的多。) 最佳答案
看到相同结果的一种更简单的方法是:
(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))
关于scheme - 为什么延续没有有用的工具?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11339541/