--- title: ダイジェスト版「コルーチン」とは何だったのか tags: coroutine, lambdanote description: 『n月刊ラムダノート』創刊記念パーティーでの発表資料 --- # ダイジェスト版 『コルーチン』とはなんだったのか 2019/05/30 『n月刊ラムダノート』創刊記念パーティー https://hackmd.io/p/S1dw4Xy2V#/ https://hackmd.io/0j1gPlznSo6JBO0MloITfA# --- ## 自己紹介 * 遠藤侑介 @mametter * クックパッドで働くフルタイム Ruby コミッタ * Ruby 3 の静的検証とかテストまわりとか * コルーチンは Ruby コミッタになったきっかけ(の 1 つ) --- ## \[ruby-dev:30827\] ささだ 2007/05/28 > Continuation のついでに Fiber を入れました。 > (略) > というわけで、皆様にいくつかご相談です。おもに、名前と機能の話です。広くご意見を頂けると幸いです。 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/30827 --- ## \[ruby-dev:31596\] 遠藤 2007/08/22 > Fiber や Coroutine という言葉には、ちゃんとした定義もコンセンサスもないようなので、はっきりいって言ったもん勝ちです。 > (略) > 短くてかっこいいのを選べばいいと思います。 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/31596 --- ## コルーチンとは * 伝統的コルーチン(2000年代まで) * なんか制御構造みたいなやつ * 2 種類ある <!-- .element: class="fragment" data-fragment-index="1" --> * async function のこと(2010年代から) * 非同期処理を楽に書くやつ * 伝統的コルーチンとは完全に別物 <!-- .element: class="fragment" data-fragment-index="2" --> --- ## 対称コルーチン 元祖のコルーチン、`transfer` で実行を渡す ```ruby A = Fiber.new { # 2. A に実行が渡された → B に実行を渡す B.transfer() # 4. A に(再度)実行が渡された → 実行終了 } B = Fiber.new { # 3. B に実行が渡された → A に実行を返す A.transfer() # ここには到達しない } # 1. コルーチン A に実行を渡す A.transfer() ``` 単純だけど使いにくいので使われていない <!-- .element: class="fragment" data-fragment-index="1" --> --- ## 非対称コルーチン resume で起動(再開)、yield で中断 ```ruby A = Fiber.new { # 2. A が起動された → 中断して呼び出し元に処理を返す Fiber.yield() # 4. A はここから再開する → 終了して呼び出し元に処理を返す } # 1. コルーチン A を起動する A.resume() # 3. A が中断して帰ってきた → A を再開する A.resume() # 5. A が終了して帰ってきた → 実行終了 ``` 2000年代まではコルーチンと言えばコレだった <!-- .element: class="fragment" data-fragment-index="1" --> 無限列の実装に使える <!-- .element: class="fragment" data-fragment-index="2" --> --- ## async function async/await: 非同期処理を同期風に書く記法 ```javascript async function asyncABC() { await sleep(1000); print("foo"); await sleep(1000); print("bar"); } await sleep(1000); print("baz"); ``` ここでの「コルーチン」=`async function` <!-- .element: class="fragment" data-fragment-index="1" --> <span><!-- .element: class="fragment highlight-red" -->**伝統的コルーチンとは完全に別物!**</span> <!-- .element: class="fragment" data-fragment-index="2" --> --- ## 背景:JSの歴史的経緯 (1/4) 1990年代:関数は即時リターンする文化 * イベントを待つならコールバックを登録する * ~~主な用途:いたずら、ブラクラ~~ * みんな JS オフにしてた --- ## 背景:JSの歴史的経緯 (2/4) 2000年代:JavaScript アプリの複雑化 * Ajax, prototype.js, jQuery * 『コールバック地獄』の発生 * インデントが無限に深まっていく --- ## 背景:JSの歴史的経緯 (3/4) ES2015:非対称コルーチンと Promise の導入 * コールバック地獄を(理論上は)解決 * でも実際にはまだまだ書くのダルい * JS 民「非同期処理はコルーチンで!」 --- ## 背景:JSの歴史的経緯 (4/4) ES2017:async/await の導入 * わりとシンプルに書けるようになった * JS 界に平和が訪れた (?) * しかし…… --- ## あらたな用語地獄 * JavaScript コミュニティの一部でコルーチンと async function がやや混同されている * async/await を輸入した Python は async function を「コルーチン」と呼んだ * Kotlin は伝統的コルーチンも async function もまとめて「コルーチン」と呼んだ すでに別の意味で定着しつつある模様 --- ## まとめ みんなが愛した伝統的「コルーチン」は死んだ * 背景や文脈によって意味が異なる * 齟齬が生じないように注意しましょう
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.