ささだです。

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