https://randomfacts.club/2 から文脈を拾い起してみたもの。書き起こしではないので、鹿野の勘違いなどによる間違いが含まれている可能性があります。
- 細切れにするのって、ある種のCPS変換ではないのでしょうか(はまじさん)
- Pythonで「awaitメソッドを細切れにする」のは、継続渡し形式に変換しているのと同じでは、という質問(鹿野)
- やっていることはCPS変換そのものだと思うが、「CPS変換」と呼ぶのが憚られて、何か別の名前があるのではないかと考えた(もり)
- 実際、質問で「ある種の」ってつけたのは、本当の継続ではない、つまりスタックっぽくないと思ったから(はまじ)
- この場合、CPS変換で渡される継続は、スケジューラに相当するのかな(まめ)
- コンパイラ視点だと、巨大なswitch文が作られていて、awaitを呼び出した単位で分かれている。CPS変換では、それぞれの関数を独立して捉えることになる。確かに、同じコンテキストを共有しているという意味ではCPSそのものだなと思った(もり)
- RubyのiteratorもPythonのgeneratorもコルーチンっぽいが、それはあってる?(κeen)
- Pythonのgeneratorは、常にスタックがあって、実行が止まっているので、対称コルーチンではない。(もり)
- が、非対称コルーチンそのもの(まめ、もり)
- ジェネレーターについては、記事でもあまり扱っていないが、実はコルーチンとジェネレーターには70年代くらいまで遡る関係があるって聞いた(鹿野)
- ジェネレーターは、コルーチンとは無関係に発明された。Pythonのgeneratorも、当初はコルーチンとは関係なく導入されたと思うけど、あるときに同じものだと誰かが気づいたのだと思う(いまい)
- ここで今井さんの紹介をしておくと、そもそもこの記事のきっかけはPythonでasync functionをコルーチンって言ってるのは本当にコルーチンなのかというところで、元々何がコルーチンかという調べものを今井さんと一緒にしていた(まめ)
- 業務でPythonで非同期処理を書いていたら、asyncioが異常に使いづらく、async functionがコルーチンって言ってるけど意味がわからんと遠藤さんに愚痴っていたら、遠藤さんが外に拡散してしまった(今井)
- そもそも同期待ちの言語であるPythonでasync/awaitがうれしいのはどんなときなのか、Rubyにも要望がきているが、実際の使い勝手がよくわからない(まめ)
- やはり同期待ちの言語であるC#でasync/awaitが有用なので。あと、JSと似たような書き方がPythonでもできるというのはある(もり)
- Pythonのasync/awaitではfutureを駆使するのだが、それを(まったく別の並行性の概念である)コルーチンと呼んでるのが混乱する(今井)
- Pythonで歴史的な経緯からコルーチンと呼ぶべきでないものをコルーチンと呼んでしまったのは、納豆と豆腐の関係のような感じがする。腐ってるほうを納豆と呼ぶのはなぜか、みたいな。それに慣れてしまうしかないのかも。ただ、Pythonで非同期処理をめぐる状況が混乱しているのは確かで、それらを相互運用するアダプターがあるのがますます混乱に拍車をかけてるっていう面もある(もり)
- C#でasyncが導入された結果なにが有用だと判断されたんでしょうか?(会場)
- インデント地獄の解消ってのがある。あとは、スコープの定義とか呼び出しとかをせずに書けるのが評価されたのかも。ほかにもいろいろあるとはおもうけど(もり)
- C#では、並行処理を直観的に記述するための手法として受け入れられたと思う。ちなみにJSでは、また別のJS特有な事情があってasyncが普及した。Pythonは、ほぼJSの状況だけ見て導入したように見える。C#においてasyncがよいと考えられた部分が、どれくらいPythonで意識されていたのかは、ぜひ知りたいところ(まめ)
- Pythonでは、yield fromで擬似的にasync/awaitのセマンティクスを実現してたところで、糖衣構文の必要性が認識され、async/awaitを見てこれだって気づきがあったのかもなあ、という推測はしている(もり)
- C#では「コルーチン」とあまり聞かないのに、Unityでよく聞くのはなんででしょうか?(会場)
- そもそもC#のasyncは本来のコルーチンではなかったが、JSの界隈で混同が発生して、その後Pythonで正式にasync functionのことをコルーチンと呼ぶようになったのが経緯(まめ)
- Unityの文化でコルーチンというのは、generator。Pythonの影響をうけてか、それをコルーチンと呼ぶようになったと思われる(もり)
- だから、Unityのコルーチンは非対称コルーチンそのもの。Unityでは、async functionのことをコルーチンとは言っていないはず(まめ)
- Unityではゲームプログラミングという文脈があり、複数の実行主体がそれぞれ独立に処理を進めながら互いに協調しながら動くという並行処理が必要なので、コルーチンは理にかなっている。それは、今で言うマルチエージェントシミュレーションをするための言語であったSimulaでコルーチンを重宝したのと似ている。(今井)
- コルーチンは非同期のためのもの?(会場)
- 非同期/同期は、コミュニケーションの手段の区別。並行性を記述するためのひとつの手段。複数の主体がそれぞれお話するときに、非同期が実装されていると、いろいろ便利。(今井)
- そもそも発明者の一人であるコンウェイは、コルーチンを扱った最初の論文で、コルーチンでCOBOLのコンパイラを実装する話を書いた(今井)
- 当時のコンピューターはソースがテープに記録されたりしていたので、それを入れ替えたりする処理をなるべく減らしたいという要望があった。コンパイラが機械語を生成するときには複数の処理があり、なかにはトークンのパース中にいったん処理を止めて結果をとるようなこともあるが、それをワンパスで済ませられる手法としてコルーチンが考えられた(もり)
- 処理がいったりきたりする複数のモジュールのそれぞれをコルーチンとして書くということ(今井)
- おかげで、構文解析の結果を磁気ドラムにいれて、次の結果をまた磁気ドラムにいれて、みたいなことをしなくてよくなったというのがワンパスの意味(もり)
- 非同期処理というのは、あくまでもコルーチンのひとつのアプリケーションだったが、いまではとても大きなアプリケーションなので、1対1のようにとらえる人が増えた、という状況だと思う。コルーチンの用途は当然ほかにもあって、いまの例のような、レキサーが次々に読み込んだトークンをパーサが受け取って構文木にして出していくというのは、ちょうど非同期と無限列の中間みたいな用途で、これもやはりコルーチンで書ける。(まめ)
- コルーチンで無いと実装不可能なものがあるなら実例が聞いてみたいです(会場)
- とくにないのでは。言語がチューリング完全ならなんでも書けるので(まめ)
- RubyではFiberという名前を選んだが、Fiberについては用語問題は起きなかった?(会場)
- スレッドより細かい実行単位というのが、もともとのMicrosoftのFiber。Rubyでは、名前がかっこいいからそれを選んだ。MicrosoftのFiberは非対称コルーチンだと思っていたら、実は対称コルーチンだった。Rubyも用語を混乱させてるかも(まめ)
- スレッドはOS由来のもので言語の機能ではなかったし、スレッドは並列を表現するものだった。神の視点では同時に動かず順番に動いていいのが並行なので、別の概念(今井)
- selectシステムコールが非常に重いので、それを避けるために非同期を使いたいという要望なども論点としてありましたか?(会場)
- あるプログラミング言語で非同期的な処理をしたいことの動機がselectの遅さにあるかというと、たぶんない。たとえばPythonのselectモジュールは、実際にはselectシステムコールを使っているわけではなく、同じインタフェースでepoll/Kqueueだったりを実装としては選べたりして、それは他の言語のライブラリとかでも似たような感じなので、そこは本質ではないと思う(もり)