2

だから私はcall/ccSchemeでこのすべてを理解しようとしています。以下は私が取り組んでいるコードです:

(+ 1 (call/cc
  (lambda (k)
    (if (number? k)
        (call/cc (lambda (k) (k (- 1 k))))
        (k 4)))))

ここで、最初の括弧内に 2 つの引数を追加し始めます。1熱心な評価のために評価しなければならない残りの部分。そのため、call/cc引数を 1 つ受け入れる関数があり、call/cc呼び出しによって評価されます。(私は正しいですか?) 同時に、これまでに起こったことの残りの部分が最初の括弧内に保持されます。つまり(+ 1 [])、これは「継続」です。(私は正しいですか?) それでk、先ほど説明したように、継続でlambda を呼び出します(+ 1 [])。関数では、これが数字であるかどうかを尋ねますが、そうではなく、「then」を実行します。ここで「道に迷った」のですが、この秒は何をしcall/ccますか? (k 4)この全体を評価するために、何が呼び出され5ますか?

4

2 に答える 2

4

あなたはかなり近いです!あなたの質問はすべて正しいと思います。

渡す関数はcall/cc(あなたの例では)1つの引数を取りk、それは現在の継続に値を返す方法です。k1つの引数の関数です。値を使用してその関数を呼び出すと、その値が返され、次の代わりになり_ます(+ 1 _)

したがって、あなたの例では、(number? k)は決して真ではなく、への2番目の呼び出しcall/ccは実行されません。(たとえそうであったとしても、(- 1 k)1から関数を減算するランタイムエラーで失敗します。)したがって、実際には「else」ブランチを実行します。(k 4)これは4を返す(+ 1 4)ため、結果は5になります。

それが明確であることを願っています!

于 2012-07-25T02:43:10.070 に答える
1

call/ccのようsetjmpです。後のコードが直接「ジャンプ」できる出口点を定義longjmpします。

そのための特定のプロトコルに従うため、常に次のように記述します

( .... surrounding code .....
   (call/cc (lambda (k)
      .... inner code which has access to the exit point "k" ....
      )) .... more surrounding code .... )

kそのプロトコルの下で、「内部」コードは通常どおり実行されますが、そのスコープには という名前もあります。の範囲外であるため、「周囲の」コードはどれもそれにアクセスできませんk

kここにファーストクラスの値があります (当然のことながら、名前が付けられています)。Scheme ランタイム システムは(call/cc ...)、舞台裏で、コール ポイントの継続を自動的に割り当てます。プログラマーの場合、アクセスできるときはいつでも使用できます。

継続は、1 つの引数の関数です。その関数が呼び出されると、その引数が継続の呼び出しコンテキストに渡されます。しかし、kはファーストクラスの名前付き値であるため、自由に渡すことができます。「内部」コードは必要に応じて複雑にすることができ、他の場所で定義された他の関数などを呼び出すことができます。そのkような外部関数に引数として渡す場合は、それを同様に使用できます。

値を指定して呼び出すkということは、元の呼び出しの呼び出しコンテキストにその値を返すことを意味し(call/cc ...)ます。直接。そこに ingと同じようlongjmpに (ただし、 だけでなく、任意の値を返すことができますint)。

于 2012-07-29T07:59:18.590 に答える