5

次のコードを検討してください。

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

ここでは、call/cc呼び出しのポイントでの継続が右側のラムダであることが非常に明白であるため、そのアリティは2である必要があります。ただし、上記の戻り値(Racket)は(arity-at-least 0)代わりになります。

実際、Guileで同様のコードを実行すると(の代わりprocedure-minimum-arityprocedure-arity)、明らかにそうではない場合でも、継続によって任意の数の引数が許可されることが示されます。

それで、それはなぜですか?私が理解している限り(私の理解が間違っている場合は訂正してください)、継続のアリティは非常に単純です。のコンテキストを除いて1ですcall-with-values。この場合、右側のラムダのアリティは何でもかまいません。(これは、当然のことながら、などの場合は複雑になる可能性がありますが、直接case-lambda電話をかけている場合ほど複雑ではありません。)(procedure-arity (case-lambda ...))

4

1 に答える 1

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)))

そしてあなたの質問のために-最初のケースでは、継続が2つの入力を期待していることは明らかですが、そのようなケースはあまり一般的ではありません。たとえば、それらは通常そのような例ですが、「実際のコード」は、作成されたコンテキストに応じて、作成するdefine-values継続が異なるアリティを持つ可能性がある、未知の継続を使用または持つ場合があります。call/ccこれは、継続のアリティが知られているこれらのまれなケースを理解しようとしてもあまり意味がないことを意味します。

脚注:

;; nonsensical, but shows the point
(define (foo) (call/cc (λ (x) x)))
(define x (foo))
(define-values [y z] (foo))
于 2012-07-06T14:01:03.350 に答える