Golang ファーストインプレッション


並行処理のタイプが全く違うので、悩ましいが、どれも違って面白い。曖昧だが自分としてはしっくりくる描写は、各言語を書く時「何が主役だと感じるか?」という印象だ。それぞれ冒頭にそのイメージを書き、その後にちょっとした特性を附記する。

  • golang: goのコード自身が主役な感じ。チャンネルでの待ち合わせ時に停止する可能性がある。コンテクスト切り替えは、プリエンプティブに勝手に行われる。メッセージは送信者も受信者も、合意の元でチャンネルを介して行う。
  • Erlang: メッセージ処理の周りにコードがくっつく感じ。メールボックスでの待ち合わせ時に停止する可能性がある。コンテクスト切り替えは、プリエンプティブに勝手に行われる。メッセージは送信者が受信者を決めてメールボックスへ送る。
  • Javascript (node): IO処理の周りにコードがくっつく感じ。他のコンテクストがCPUを独占している間、停止する可能性がある。非同期関数の呼び出しによる(半)明示的なコンテクスト切り替え。メッセージは同一オブジェクトへの参照を介して授受する。(Node.js clusterにより複数プロセスにまたがる時は、メッセージイベントにより授受する)
  • Lua (OpenResty): ホストプログラムの周りにコードがくっつく感じ。他のコンテクストがCPUを独占している間、停止する可能性がある。coroutineのメソッドによる明示的なコンテクスト切り替え。メッセージは同一テーブルへの参照を介して授受する。

こう書くと、何だか、golangとErlang、Javascriptとluaが似ているかのようだが、それぞれの書き味はかなり違う。golangは良くも悪くもC系のスクリプトを書いている感じで、メッセージ授受はあくまでシンプルなメッセージ送受信ライブラリを使っているかのようだ。いい加減な例えで申し訳ないけど C++ で演算子オーバーロードを使ったライブラリを使っている手応えに似ているかもしれない。いずれにせよ、メッセージ授受を書く場所を選ばないように感じる。Erlangはメッセージ送受信を中心に書く感じで、メッセージ処理スクリプト、というイメージだ。Javascriptとluaの差は、まあここでの話題から外れるし、Javascript(node.js)の「抜け道の多さ」みたいなものを説明するだけでかなり文章を費やしそうなので、割愛する。

なので、 golang では、メッセージパッシングの文脈上のタイミングが自由な分、メッセージ体系を慎重に組み立てないとヤバいことになる予感がする。また、メッセージパッシングが主従の「従」になるので、 golang で書いたコードは、Erlang, Javascript, lua には訳しにくそうだ。むしろ、 C++, Java, C# みたいなC系の言語との相互訳のほうが容易そう。いずれにせよ、golangは他の言語では状態変数や(EventEmitterみたいな)イベントラベルなどの状態を持つべきところを、チャンネルがそこここに挟まった制御フローとして記述できる可能性が高いように思う。どちらが書きやすい、というものでもないが、ライブラリ作者には辛く、アプリケーション作者には優しい、というのが文字通りファーストインプレッションだ。そのあたりはもう少しパターンを知らないと確かなことは言えない。

また、これも、もうちょっと書いてみないとわからないけれど、ウェブアプリを書く際、セッション毎にgoroutineを立ち上げて、ページ遷移やSPA内状態遷移を、そのまま制御フローとして書く、というような可能性も感じる。そういう書き方はしてみたかったので、目下それを実現する、というマイルストーンをおいても良いかもしれない。言葉としては単純だが、某ライブラリ同様、外観デザインとの分離が難しくなる予感がするけどね。

とりあえず、あまりに違って混乱しそうにないので、CoffeeScriptとのマルチリンガルのまま進めりゃ良いじゃん、ということになった。ちゃんちゃん