遠藤です。

> いろいろと Fiber の仕様を悩んでいたんですが,決めました.で,実装
> してコミットしました.

お疲れ様です。面白いものをありがとうございます。
さっそく遊んでみたのですが、残念ながらコルーチンとセミコルーチンは
相性が悪いことに気がついてしまいました。


Fiber の中で Fiber::Core を終わらせると、その時点で実行中だった
Fiber が「生きながら永遠に実行されない?」状態になります。

f = Fiber.new do
    Fiber::Core.new { }.transfer
    p 1  # ここは永遠に実行されない?
end
f.resume
f.transfer
f.resume #=> double resume (FiberError)

要するに、「Fiber をネストしたら変なことになる」という問題が「Fiber の
中で Fiber::Core を使うと変なことになる」に変わったようです。


例えば Generator の中で Fiber::Core に transfer すると、Generator から
next を取ろうとするしたとき変なことになります。

def (o = Object.new).foo
    yield 1
    yield 2
    yield 3
    Fiber::Core.new { }.transfer
end

g = o.to_enum(:foo)
p g.next #=> 1
p g.next #=> 2
p g.next #=> nil  (?)
p g.next #=> double resume (FiberError)  (??)


解決の方針をいくつか考えてみました。

- Fiber::Core をなくす
- Fiber::Core の終了時の戻り先を root fiber 以外にする (じゃあどこ?)
- Fiber::Core を呼び出せるのは root fiber だけ、にする (不便そう)
- Fiber::Core は callcc 並の黒魔術である、とレッテルを貼って使わせない



名称については、私は Fiber のままでもいいと思います。
Fiber や Coroutine という言葉には、ちゃんとした定義もコンセンサスも
ないようなので、はっきりいって言ったもん勝ちです。
Lua だって自分たちで "Semi"-coroutine と認めているものと Coroutine と
呼んでるわけですし。
だから短くてかっこいいのを選べばいいと思います。



おまけ。以下で落ちました。継続が呼び出せてる時点で何か間違い?

i = 0
callcc {|c| $c = c }
raise if i == 2
i += 1
Fiber::Core.new { $c.call }.transfer

-- 
Yusuke ENDOH <mame / tsg.ne.jp>