ElixirとPhoenix
Elixirは関数型プログラミング言語として優れており、(私見では)Elixirの目標は、開発者の幸福やまっとうな生産性にも配慮しつつ、マルチコア処理(コードの実行速度)とソケット接続をサポートすることにあります。
PhoenixはElixir言語で構築されたWebフレームワークですが、Phoenixを知れば知るほど、PhoenixとはElixir言語と同じ目標を共有しつつElixirと協調動作するライブラリの集合体であることがわかってきます。すなわち、言語とフレームワークの間に哲学上の大きな葛藤がありません。
Elixirは、きわめて強力な関数型言語であるErlang VM上に構築されています。Erlangは、フォールトトレーランスを保証するシステムを必要とする通信業界向けに設計されており、山間部の通信塔設備において99.9999999%
という優秀なフォールトトレーランスで動作します。
Erlangが満たしている通信業界の厳しい要求のひとつに、ある通信塔が他の通信塔の責務を代行することで発信元からの通信が途絶しないようにすることがあります。そしてErlangのこの分散処理能力がマルチコア通信の要請に最適であることに一部の賢い人々が気づきました。つまり、多数のCPUコア(32、64、あるいはそれ以上)を持つサーバーマシンでは、ErlangがアプリをすべてのCPUコアで効果的に走らせることができます。
「マルチコアを扱えるオブジェクト指向言語なら既にたくさんあるじゃないか(JavaはもちろんRubyも含めて)」というご意見もおありかと思います。ここで皆さんに知っていただきたいのは、あらゆるオブジェクト指向言語はマルチコアではいいところがないという点です。もちろんマルチコアでも動くは動くのですが、関数型プログラミング言語ほど目覚ましい成果は得られません。
諸悪の根源は「ステート」です。CPUコア同士がミューテーションなしでステートをやりとりするのは恐ろしく困難です。オブジェクト指向とは、行った結果であるステートを関数に加えることだからです。
関数型プログラミング言語はステートを改変しないので、副作用が生じないということになります(詳しくはこちらのブログ記事をどうぞ)。
画像:「何がむかつくって、グローバル変数を普段ほいほい改変しておきながら『AIが世界を支配する』とかぬかす開発者だよ」
ElixirはErlang上で構築されているがゆえに、この恩恵も受けられるわけです。
ソケット接続も重要な点です。あらゆるWebサーバーは、通信をリクエストとレスポンスという形で取り扱うことはご存知でしょう。しかしチャットやビデオ会議などのリアルタイムアプリを構築するのであれば、「ソケット」でサーバー上の接続を維持する必要があります。
現在のRailsやJavaは、1台のサーバーで一度に数千個の接続を扱えます。
一方、ErlangとElixirなら2百万接続を扱えます(傍証: ErlangとElixir)。実を言えば40コア程度のCPUとメモリ128GBのサーバー上の軽量な接続なのですが、それを差し引いてもかなり印象的です。
つまりElixirとPhoenixの凄さは本物なのです。それならもっと使われてもよさそうなものですが、上述のとおり、何事もコストを無視するわけにはいきません。PhoenixとElixirは生産性の向上に最善を尽くしてくれるのでしょうか?将来の大規模なスケーリングを約束する技術を取り入れるとなると、癒着を切り離す方法を導入する必要が生じ、その分開発者の進捗が少々遅くなります。
「モデル」からデータベースへの書き込みはそのよい例です。(スキーマを持つ)モジュールが変更セットを呼び出し、その変更セットがリポジトリを呼び出し、そしてそのリポジトリがデータベースに書き込む必要があります(例)。Railsでは、この3つのステップが1つにまとめられています。
ステップを3つに分ける方がコーディングにおいてずっとよい結果をもたらします。コードが分離されることでテストが容易になるからです。しかしその分、Railsで書くときよりも明らかに時間がかかります。Railsはコーディングの実践という点では見劣りしますが、Railsは生産性と実装速度を高めることに特化しているのです。
これは「設計上の選択」とは別の話です。関数型プログラミングではコードの書き方がより明示的になる分、すべてを渡す必要があるので、よくも悪くもコードは複雑になります。
高トラフィックに耐えうるアプリを構築する場合、ソケット通信に強く依存するアプリを構築する場合、納期に余裕を持てる会社で働いている場合は、ElixirとPhoenixを使いましょう。
慌てて列車に飛び乗る前に、ElixirとPhoenix関連のトークをご覧ください。これらのトークは、皆さんが迷いを振り切って意欲的に取り組み、コードのみならず哲学をも理解するのに役立ちます。次の2つをおすすめします。
- 動画: Lonestar ElixirConf 2017- KEYNOTE: Phoenix 1.3 by Chris McCord
- 動画: Jose Valim – Idioms for building distributed fault-tolerant applications with Elixir
JavaScript
フロントエンドWeb開発者がサブプロジェクトをフルスタックで構築するのであれば、最小限のJavaScriptの知識は不可欠です。したがって、どの道に進もうとJavaScriptはある程度ものにしておいてください。
私はバックエンド方面で数年ほどあるサブプロジェクトに従事していましたが、当時についてはろくな思い出がなく、もう戻りたいとは思いません。当時の良し悪しを云々したいのではなく、単に私の選んだ道が正しくなかったということです。バックエンド系のJavaScript開発者で幸せそうにしている人がたくさんいることもある程度承知しています。私はその一人ではなかったというだけのことでした。そういうわけで本記事ではJavaScriptについてあまり書かない予定です。
最近よかった議論としては、現代のWebアプリではバックエンドをNode.js(JavaScript)で書き、フロントエンドをReact.jsかAngular.jsかVue.js(いずれもJavaScript)で書き、バックエンド開発者とフロントエンド開発者がJSON(JavaScript Object Exchange)でやり取りし、データベースはJSONドキュメントを保存できるMongoDBにすればいい、というのがあります。
Web開発のエクスペリエンス全体が、プログラミング言語を1つだけ習得すればいいという流れになっているように感じられます。コーディングブートキャンプがJavaScriptを好むのも、その方が単純になるのですから当然でしょう。
しかし1つ前のセクションでも申し上げたとおり、プログラミング言語を1つ学べばすべてOKということは永遠にありえません。プロとして仕事をしていれば、いずれ自分のツールボックスに新しい言語というツールを付け加えなければならなくなるでしょう。
Node.jsでバックエンドを構築していれば、同期的なRuby MRIの思想といささか異なる「イベントループ」というものと取り組むことになるでしょう。私が何を言っているのかわからない方で、かつRubyを使える方であれば、Node.jsのイベントループと似た原則を用いるEventMachineで遊んでみるとよいでしょう。
JavaScriptのもうひとつのメリットは、AWS Lambdaなどの多くのFaaSプロバイダでサポートされていることです。
最後に
学ばなければならないことは、本当にいくらでもあります(私自身そうです)。何をするにしても、暇を見つけては本を読んで勉強し、多くのコーディングを実装しなければなりません。さもないと、どんな言語を選ぼうと無駄になります。
今後数年の間役に立つおすすめのトピックをリストアップします。
- オブジェクト指向と関数型プログラミングの両方に挑戦する
- SOLID原則、DCI、シンプルデザイン、オブジェクトのコンポジションを学ぶ
- デザインパターンを学ぶ(Martin Fawlerなどで)
- DDD(ドメイン駆動設計)を学ぶ
- Bounded Contexts(コンテキスト境界)を学ぶ
- TDDやBDDを用いる理由と、TDDやBDDをやめる理由
- バックエンド開発者であってもフロントエンド開発に挑戦する
- 開発のプロになる方法を学ぶ(書籍『Clean Coder』など)
- マイクロサービスに挑戦し、それからマイクロサービスを使うのを「やめる」
TDDやSOLID原則などの技法は有用ですが、いつどんなときも正しいというものではありません(もう申し上げましたよね!)。こうした技法を盲信しないことです。これらの技法の値打ちは、それらを学んで必要に応じて適用することにあり、技法に偏りすぎて生産的なチームを損なうことではありません。チームのよい一員であることの方がよほど値打ちがあります。
最も重要なことは、空き時間に自分だけのプロジェクトを持つことです。実験的なことは業務以外のプロジェクトで行い、そこで得られた知見を仕事に反映しましょう。
「自分の時間を潰してまで何かを学ぶつもりはない、今の会社で必要なことをその場で学べばいい」という態度は、開発者として最悪です。Web開発者とは単なる仕事ではなく、生き方なのです。Web開発者としての人生を歩みましょう。
本記事に関連する議論
- Redditの議論
- RubyFlowでの議論
- Hacker news(これは私が始めたのではなく、いつの間にかスレが立っていました)
- Changelogニュース
訳注: Martin Fowler「Refactoring 2nd Edition」がつい最近リリースされました。