コルーチン
#coroutine
用語
symmetric coroutine/asymmetric coroutine
RubyのFiberでいうとFiber.transferがsymmetric (どのFiberに飛ぶかをプログラマが指定する
普通のFiber.yield、Fiber#resumeがasymmetric
stackless coroutine/stackful coroutine
コルーチン内でのみyieldできるのがstackless
eg. C++20, LLVM
Rust
js, Rustのasync/awaitはgeneratorで実装されている?
コルーチン内の無名関数や呼んだ先の関数でもyieldできるのがstackful
eg. RubyのFiber
stackfulness of coroutines \- lilyum ensemble
stackfulness = 「コールスタックをまたいで yieldできるかどうか」
(ちなみに)言語によってその他のものをコルーチンと呼ぶことがあるという話:新雑誌「n月刊ラムダノート」の『「コルーチン」とは何だったのか?』の草稿を公開します - まめめも
実装
ruruby: RustでつくっているRuby - Qiita
stacklessならステートマシンに変換できるが、stackfulは実装が大変という話
Stackful coroutine実装まとめ - Qiita
libcoro で並行処理プログラムを書く
【Swift】async/awaitはどのようにして動いているのかLLVMのレベルで調べてみる - Qiita
20分くらいでわかった気分になれるC++20コルーチン
stackless vs. stackful
c++ - How do stackless coroutines differ from stackful coroutines? - Stack Overflow
stacklessはコルーチンから呼んだ先の関数内でyieldできない
≒自分で定義した関数内でしかyieldできない
以下のyieldでfooから抜けるなら、stackfulでないといけない (RubyのFiber.yieldはこれができる)
code:sk
def foo
ary.each do |x|
yield x
end
end
関連して、jsで複数の
code:js
urls.map(async function(url) => {
return await HTTP.get(url)
})
// こうすると「結果の配列」ではなく、Promiseの配列ができる
// (Promise.allでまとめて解決してやることは可能)
// forだとこう書ける
ary = []
for (url of urls) {
ary.push(await HTTP.get(url))
}