1

式には、 、 、 の(call/cc (lambda (k) (k 12)))3 つの継続があります。「現在の継続」はどれ?(k 12)(lambda (k) (k 12))(call/cc (lambda (k) (k 12)))

また、いくつかの本では継続は、値を待っている手続きと見なされ、値に適用されるとすぐに戻ります。そうですか?

現在の継続とは何かを詳しく説明できる人はいますか?

4

2 に答える 2

2

のような(k 12)ものは続きではありません。一部の大きなプログラムでは、各部分式に関連付けられた継続があります。たとえば、 in の続きx(* 3 (+ x 42))です(lambda (_) (* 3 (+ _ 42)))

あなたの例では、「現在の継続」は、(call/cc (lambda (k) (k 12)))その式を囲むものです。スキームプロンプトに入力しただけの場合、それを囲むものは何もないため、「現在の継続」は単に(lambda (_) _). のようなものを入力した場合(* 3 (+ (call/cc (lambda (k) (k 12))) 42))、続きは(lambda (_) (* 3 (+ _ 42))).

「現在の継続」を表すために使用したラムダは、渡されるものと同じではないことに注意してくださいcall/cc(例で名前が付けられkています)。k現在の継続を評価した後、残りの計算を中止する特別な制御効果があります。

于 2012-10-03T20:21:21.430 に答える
1

この場合の継続は、call/cc呼び出しの戻り値を受け取る「もの」です。したがって:

(display (call/cc (lambda (k) (k 12)))

と同じ結果になります

(display 12)

Scheme の継続は、プロシージャのように「ルック アンド フィール」しますが、実際にはプロシージャのように動作しません。継続をよりよく理解するのに役立つことの 1 つは、CPS 変換です。


CPS 変換では、関数が値を返す代わりに、継続パラメーターを取り、結果で継続を呼び出します。したがって、CPS 変換さsqrtれた関数は(sqrt 64 k)、8 を返すのではなく(k 8)、末尾の位置で呼び出すだけで呼び出されます。

(CPS 変換された関数内の) 継続は末尾呼び出しであるため、関数は継続が戻ることを心配する必要がなく、実際、ほとんどの場合、継続が戻ることは期待されていません。

これを念頭に置いて、関数の簡単な例を次に示します。

(define (hypot x y)
  (sqrt (+ (* x x) (* y y))))

およびその CPS 変換バージョン:

(define (hypot x y k)
  (* x x (lambda (x2)
           (* y y (lambda (y2)
                    (+ x2 y2 (lambda (sum)
                               (sqrt sum k))))))))

*(継続引数を受け入れるために、 、+、およびsqrtもすべて CPS 変換されていると仮定します)。


ここで、興味深い部分: CPS 変換call/ccには次の定義があります。

(define (call/cc fn k)
  (fn k k))

CPS 変換により、call/cc理解しやすく、実装も簡単です。CPS 変換がなければcall/cc、非常に魔法のような実装が必要になる可能性があります (たとえば、スタック コピーなどを介して)。

于 2012-10-03T02:33:52.870 に答える