From: SASADA Koichi Date: 2007-06-15T00:39:46+09:00 Subject: [ruby-dev:30988] Re: Supporting Fiber  ささだです。 Yusuke ENDOH さんは書きました: >> > Lua の coroutine は semi-coroutine で、coroutine 間に親子関係があり >> ました。 >>  Pythonと同じですね。 > > Python は関数内にレキシカルに yield があるときだけ coroutine 化 > (というか generator 化) する、という違いはあるようです。  確かに。実行モデルという点で同じだという意味でした。失礼しま した。 >>  中途半端ととるか、Ruby らしいいいとこ取りととるかは人による >> 感じでしょうかね。「親子関係をもったような何か」もやりやすい >> し、「対等な関係」を実現することも可能、というように作りました。 > > 残念ながら今のところ、どちらもやりにくいと思います。 > 対等な関係は callcc でやれってことにして、Lua 式に従うとか。 > # 個人的には Lua 式 (≠ Python 式) が好みになってきました。  「やりづらい」という根拠はどの辺でしょうか。「遠藤さんにとっ てわかりづらい・直観的ではない」というところかな。  Coroutine としての表現力を落としたくない、でも、親子関係を 使ったプログラミングをしたい、という、確かに中途半端な目的でこ ういう仕様にしています。  親子関係を利用したプログラミングをしている場合、「親子関係の 破壊を起こさなければ」、Fiber#prev が正しく「呼び出し元」を指 し示すため、SemiCoroutine のような使い方が可能です。  Fiber 自体の対等な関係を利用したプログラミング(複雑な状態遷 移を行う場合)では、終了時には自明ではないので「気をつける」必 要があると思います。  ただし、上記プログラミングをサポートするような、例外などを投 げる機能を追加することはできません。たとえば、Python では Generator の入れ子、つまり親子関係の破壊を行おうとすると例外が 発生します。Fiber の場合は、これを許したいため許容しています。 (この辺が中途半端)  目的が違うので「別モノ」(CoroutineとSemiCoroutine相当)を用 意するのが正しいのかもしれません。  でもなぁ。lambda と proc の例もあるので、今のままでもいいよ うな、lambda は lambda で混乱を招いているような(つまり、以前 にも書きましたが、factory によって性質を変える)。 例: Coroutine < Fiber SemiCoroutine < Fiber もしくは  Coroutine = Fiber(名前変更) SemiCoroutine < Fiber ----  余談ですが、現在の Ruby の Continuation は欠陥品で、まともに 利用できないシロモノです。具体的には、dynamic-wind 相当の機能 がありません。なので、「xx の代わりに Continuation を利用」と いう選択肢はありえないと考えています。  じゃぁ、なんでそんな欠陥品を入れておくんだ、という意見に対し ては「それでもほしい人が居るため」ということになると思います。 そもそも、ほしいという人は、この欠陥に気付く用途には使っていな いのかなーと思います。  ちなみに、dynamic-wind 相当の機能を入れるのは、拡張ライブラ リを全部 callcc safe にする作業に相当しますので、現実的じゃな いんじゃないかなぁ、と思っています。  Fiber を、わざわざ Continuation 以外で実現したのは上記の理由 からです。Fiber は Continuation に制限をかけたものですが、この 制限が dynamic-wind を不要にしています。 > じゃあ Fiber.root に例外を投げたらどうでしょう。 > わかりにくい異常な挙動をするより、わかりやすい異常な挙動を > してくれた方がマシな気がします。  それも一案ですね。Fiber終了時に取りえる挙動の選択肢をまとめ ます。 (1) 今の Fiber (2) Root Fiber へ例外 Root Fiber だったら Thread を終了 (3) Thread を終了(Modula-2 / Win32) (4) 「親」(呼び出し元)へ例外(Lua/Python)   -> Coroutine としての表現力を制限させる必要アリ Root Fiber だったら Thread を終了 (5) 未定義にしちゃう -> (1)  個人的には、「主観的な感想」ではたぶん説得力がない気がするの で、実際にいくつか現実的な例を出して、プログラミングをしてみて から考えるのがいいような気がしています。  で、実際にいくつか使ってみた例(Generator / サンタクロース問 題)では、Fiber を終了させる必要がなかったという。やっぱり Fiber を終了させるというのは異常動作なのか? -- // SASADA Koichi at atdot dot net