2012-07-05 8 views
5

は、次のコードを考えてみましょう:継続はなぜ有用なものではないのですか?

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

それはcall/ccコールの時点での継続はとてもそのアリティはしかし2、戻り値である必要があり、右側のラムダであることをここでかなり明白です(ラケットで)上記の代わりに(arity-at-least 0)です。

実際にGuile(をprocedure-arityに置き換えて)で同様のコードを実行すると、継続が引数の数をいくつでも許していることがわかります。

だからこそ、なぜですか?私の理解が間違っていれば、正しいと思っている限り、継続のアリティはかなりわかりやすいです:call-with-valuesという文脈を除いて1です。この場合は、右側のラムダのアリティが何であれです。 (どちらが、許可され、それがcase-lambdaなどだ場合、複雑ませんが、あなたが直接(procedure-arity (case-lambda ...))を呼び出した場合よりもより複雑にすることができます。)同じことを確認するために

+0

IMO、それは継続が実際に呼び出されるまで、明示的な継続がコール/ ccで使用して作成されたときのように、コンテキストが不明である、任意の数の引数でなければなりません。仕様(R5/6)の「値」の定義はこれをうまくまとめていると思います。 – leppie

+0

私は、どのように '値'が継続が任意のアリティを持っていることを意味するかについてはあまりよく分かりません。あなたは、継続がサポートしているものとは異なる数の値を返すことはできません。 :() '(+(値1 2 3)42)'は有効ではありません。このコンテキスト(R5RSで定義されている 'values 'を仮定)では、 –

+1

また、 'call-with-values'では* consumer *がプロデューサ*ではなくアリティを決定します。 – leppie

答えて

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

待って、継続のアリティが捕まえられた時があると言っていますか?たぶん私はこれについて十分に懸命に考えていないでしょう。 –

+0

ええ、脚注を参照してください。これらの連続のそれぞれが動的に異なるアリティを得ることを望んでいない限り(しかし、私は走らなければならないので、これでもっと時間を費やすことはできません) –

+0

ダイナミックなアプローチは確かに私が質問したときおそらくそれは実行可能ではありません。これが機能するかどうかを確かめるために概念の証明を作成してみるべきです。一方、大きな緑のダニがあります。つまり、あなたは2ヶ月待っています。 :-) –

関連する問題