From: SASADA Koichi Date: 2007-06-12T04:05:10+09:00 Subject: [ruby-dev:30958] Re: Supporting Fiber  ささだです。 Yusuke ENDOH さんは書きました: > 一般的な意味にあわせるのが一番いいと思います。 > > 不勉強ながら私は fiber や coroutine 関連の論文や他言語の仕様を > 読んだことがないので、その答えはわかりません。すみません。 > 私が [ruby-dev:30924] の挙動に違和感を覚えた理由は Fiber の意味を > callcc の単純なラッパとして理解していて、それと同じ挙動を期待したからです。 > つまり、[ruby-dev:30924] は以下とほぼ等価かと。 > > f = proc do |prev| > p 1 > prev.call > p 2 > end > > f2 = proc do |prev| > callcc {|current| f.call(current) } > end > > callcc {|current| f2.call(current) } > > # 脳内変換規則 > # Fiber.new ==> proc {|prev| ... } > # Fiber#yield ==> callcc {|current| self.call(current) } > > > しかしこの変換規則だと Fiber を導入する意味がほとんどなさそうなので > こちらの方が一般的に採用されているとか、便利な例が多そうだということなら、 > 私の違和感は無視してください。  ほかの言語の例は実は試していないんですが、win32api の Fiber は SEGV しました。これはあんまりだ。  確認しているのは lua と modula-2 なんですが、それぞれ Fiber (Coroutine)の終了時にはどうなるのか教えてくれる人はいないで すかね。lua なら試せるかな。  とりあえず、いくつかアプリケーションを作ってみてから考えたほ うがいいような気がしています。 > あ、あと、呼び出しを Fiber.new { ... }.yield でくくるだけで挙動が変わる > 関数が定義できてしまうことに抵抗があったというのもあります。 > そういう黒魔術は callcc だけでいい、みたいな。 > > def foo > Fiber.new do > p 1 > Fiber.prev.yield > p 2 > end.yield > end > > # Fiber.new do > # 何かいろいろやる > foo > # 何かいろいろやる > # Fiber.new でくくっていると忘れた頃に p 2 が実行される > # end.yield  表現力の高い coroutine を実現するための仕組みなので、(わか らないと)不思議なことがあるのはそういうものかなぁ、と思いま す。また、ほかの例でも同じような現象が起こります。たとえば、 Thread#pass(Thread#critical)では同じようなことが起こります が、これは黒魔術でしょうか。  ただし、過剰な自由度は混乱させるだけな気もしています。なの で、たとえば python のような制限付き coroutine のようにして提 供するのも一案かと思っています。  ちなみに、python では generator が終了したら例外を返します。 これはこれで納得できる話です。 -- // SASADA Koichi at atdot dot net