稲葉です。 多少callccと遊んだ経験を元に説明しようと思ったら、まだまだ経験値が 足りない事に気が付いてしまいました^^; すみません、混乱を助長するだけのメールかも知れません。 toyofuku / juice.or.jp wrote: > > 豊福@パパイヤです。 > > > 「スタックの深い方へ継続するときはジャンプ前のスタックポインタ > > からジャンプ後のスタックポインタまでの差分分のスタックだけを > > 復活して継続する。上の例では (0..2) の eachメソッドのスコープ > > に関するスタック(ループカウンタがここに入る)だけが復活した > > ので、ループカウンタの値だけが callcc時の値(つまりループの > > 1回目)に戻った。」 > > と想像したのですがあってるでしょうか。 自分はcallccをスタックポインタを考えて理解する仕方をしていないので、 フォローしなかった(できなかった)のですが、 > これの答はわからないままですが、これがあってるにしろ、あって > ないにしろ次のようなときスタックがどうなるかもよくわかりません。 > > def foo() > x = 1; foo1() > x = 2; foo2() > end > def foo1(); y = 10; foo11(); end > def foo11(); z = 20; callcc { |$cont| }; end > def foo2(); $cont.call; end > > $cont.call した直後の x, y, z の値はどうなりますか。 > 2,10,20 でしょうか。 foo()を呼んだ時ですね。 $cont.call の直後はfoo11()のcallcc{}の後に戻り、ここでz==20ですね。 x,yはここでは未定義です。 その後foo1()内からfoo11()を呼んだ直後にもどり、ここではy==10でx,zが 未定義です。 その後foo()内からfoo1()を呼んだ直後にもどり、ここでx==2になってい てy,zが未定義です。...と思ったのですが、実はx==1にもどるのですね。 うーーーーん、継続をcallした時、ローカル変数へ代入した値も保持され ると思っていたら、method内のローカル変数は戻るんですね。procの動的 ローカル変数と、トップレベルのローカル変数は戻らないのですが。 ------------------------- $n = 0 x = 0 callcc {|$cont|} puts "#$n) x = #{x}" x = 1 exit if ($n+=1) == 2 $cont.call #0) x = 0 #1) x = 1 ------------------------- $n = 0 def foo() x = 0 callcc {|$cont|} puts "#$n) x = #{x}" x = 1 exit if ($n+=1) == 2 $cont.call end foo #0) x = 0 #1) x = 0 ------------------------- $n = 0 foo = proc { x = 0 callcc {|$cont|} puts "#$n) x = #{x}" x = 1 exit if ($n+=1) == 2 $cont.call } foo.call #0) x = 0 #1) x = 1 ------------------------- ここまでは昨夜のうちに書いてあったんですが, Schemeではどうなるかを チェックしてから出そうと思って出しませんでした. 少なくともSCM 5c4とguile 1.3では, 代入した値が保存されますね. ruby で合わせるのが簡単かどうか, (そもそも合わせるべきかどうかも)わかり ませんが. ------------------------- (define call/cc call-with-current-continuation) (define $n 0) (define $cont #f) (define (foo) (define x 0) (call/cc (lambda (cc) (set! $cont cc))) (display $n) (display ") x = ") (display x) (display "\n") (set! x 1) (set! $n (+ 1 $n)) (if (= $n 2) (exit)) ($cont #f)) (foo) ;0) x = 0 ;1) x = 1 -- 稲葉 浩人 <inaba / sdd.tokyo-sc.toshiba.co.jp/inaba / st.rim.or.jp>