Kotlin 1.1
来た。ので手元の書きかけ Kotlin コードをちょっと書き換えてみる。ただ async/await はまだちゃんと調べてないので後回し。type alias と bound callable references はすぐ使えて良い。
Bound callable reference, 便利だけどいよいよ currying 的なことがしたくなる。このへんの高階関数の扱いは Scala の方がいいなあ。JS ですら bind があるというのに...他はそんなに不満ないのだが。
結局 async/await というか Coroutine の資料も読んだ。この入門的な記事を読み、次に適当にコードを参照しつつ詳しいバージョンを読み、最後に高位の API の説明を冷やかせばだいたいわかると思う。Kotlin は最近の言語に漏れず API リファレンスから GitHub のコードに飛べるのが便利だね。
Python の generator/coroutine をなんとなくわかってるという自分の理解からみた要点:
- 一番下にあるプリミティブは suspend キーワード, Continuation インターフェイスと suspendCoroutine() 関数。suspend キーワードのついた関数は、匿名クラスの Coroutine と、それを呼び出すスタブのメソッドを生成する。Coroutine の匿名クラスは Continuation インターフェイスを実装している。suspendCoroutine() を使うと、suspend 関数の中から自分自身の coroutine オブジェクトに (Continuation インターフェイスを介して) アクセスできる。このオブジェクトを非同期な API のコールバックから呼び出して継続する。
- Python の generator は suspend するたびに値を返せるが、Kotlin の Coroutine は最後に一つだけ値を返す。途中の suspend では値を返さない。buildSequence() などは generator みたいなもんだけど、これは coroutine のプリミティブの上でライブラリとして実装されている。
- Python の generator 関数は generator を返すが, Kotlin の suspend 関数は何も返さない。かわりに暗黙の引数として Continuation オブジェクトを渡す。CPS スタイルってそういえばこういうかんじだったかもしらん。
第一印象。Python と比べると、後出しだけあって Kotlin の方がだいぶいいと感じる。整然としており、ドキュメントを 2,3 種類読んだだけで概要を把握できる。 Python の generator/coroutine はいくつ資料をよんでもなんとなくしかわからない。そしてそれは自分だけではないっぽい。
整然としているのは、まず JVM が変化せずコンパイラの力だけでがんばっているぶんレイヤリングがうまくできているおかげ。これは C# や JS もそうかな。コンパイラが生成するコードをなんとなく理解できれば一番下のレイヤがわかる。Python はインタプリタを拡張して色々やっているせいでシステムとして理解するのが辛い。
レイヤリングという点で、コンパイラの仕事や言語本体の拡張が割と小さいのも良い。Continuation インターフェイス、suspend キーワード、suspendContinuation() instrisics 関数。プリミティブはほぼこれだけで、あとはライブラリ。わかりやすい。他の言語はもうちょっといろいろ言語本体に入ってしまってるよね。たとえば JS の async/await は Promise とくっついている。
型が静的なのも良い。Python はある関数が generator かどうかを混同しがちで辛かった。動的型というのはそういうものだけれど、実行時にしかわからないバグの原因が増えると動的型でがんばるの段々辛くなっていく。Kotlin は suspend 関数を間違ったコンテクストで呼ぶことはできないので安心。
Java 資産との乖離が心配だったけれど, ライブラリの API が RxJava など限られた非同期フレームワークに集約されている限りは RxJava と coroutine の interop を使えるので割と大丈夫なかんじ。ハードコア Kotlin プログラマは coroutine をばりばりつかったライブラリとかを作りたいだろうけれど、ライブラリは Java と Rx にしておきアプリのレイヤでだけ coroutine をつかうくらいが無難な気がする。
Kotlin 1.1 ではまた experimental というから様子見。そのうち思い出したにはいいかんじに普及していることでしょう。