KIMURA Shigenobu
skimu****@mac*****
2003年 2月 5日 (水) 12:33:47 JST
On 2003.Feb.4, at 19:33 US/Central, Makoto Satoh wrote: > 継続とは何かについて質問させて下さい。 とりあえずは「リターンアドレス」でいいと思います。 ほんとは、もっと深い概念なんだけど、 とりあえず「リターンアドレス」としての性質を押さえて、 慣れてしまえば、それほど引っかからなくなるんじゃないかと 思います。 ご存じのとおり、Scheme の関数呼び出しは引数付き goto で、 関数呼び出しのとき「ここに戻ってきてね(次はここだよ)」と いいながら隠れた引数として「リターンアドレス」も渡します。 呼び出された側は処理が終わるとその値を引数として「リターンアドレス」 を呼び出します。 別ないい方をすると関数呼び出しのたびにその呼び出しに期待する 返り値の個数(普通は一つ)だけ引数を持つ関数が作られて、 その関数--続きをする関数--が継続なわけです。 で、call/cc というは隠れた変数である継続を引っ張り出す関数なのです。 > # この後に、「現在の継続とは、call/ccを実行した後に評価すべき式 > # の情報のこと」という文があるのですが、これも良く分かりません。 > # つまり、何が(どれが)その(call/ccを実行した後に評価すべき「式」 > # なのか分からない、ということです。 「現在の継続」はなにも call/cc だけに関わるのでなくすべての 呼び出しに結びついてます。 プログラムの現在地「プログラムカウンタ」見たいなものとおもうと 分かりやすいかも、 たとえば、 (f1 (f2 val)) という式があったとして、これは、 tmp = f2(val) v = f1(tmp) てな感じに実行されて v が式の値になるんですが、もう少し細かくみると、 cont0(cont): f2(val, cont1) ;; f2 は cont1() を呼び出すことにより返り値を返す。 cont1(tmp): f1(tmp, cont2) ;; f1 は cont2() を呼び出すことにより返り値を返す。 cont2(v): cont(v) となり、 (f1 (call/cc func)) ならば、 cont0(cont): call/cc(func, cont1) cont1(tmp): f1(tmp, cont2) cont2(v): cont(v) となるんですが、call/cc は func(cont1) を実行します。 --skimu P.S. かえって混乱しちゃったら、読まなかったことにして下さい。