[翻訳] なぜ私はElixirに賭けたか - メンテナンスプログラマになりたくなければ君もそうしろ

Ken Mazaikaさんの2015年1月31日付のブログ記事、[Why I’m betting on Elixir
　And why you should too, unless you want to become a maintenance programmer.](https://medium.com/@kenmazaika/why-im-betting-on-elixir-7c8f847b58)の翻訳です。


[[翻訳] Elixir - 次に来る大物Web言語](http://qiita.com/HirofumiTamori/items/0dfdbada30c7d8f183fd)もそうでしたがなんか**Rails**のプログラマさんたちがやたらアツく語ってるんですね、**Elixir**を。
メンテナンスプログラマになりたくなければ[^0]、なんてタイトルからして挑発的です。私の3つ前の仕事はまさにそういう保守系でしたけど。
[^0]: (2006年のblog、[The Noble Art of Maintenance Programming](http://blog.codinghorror.com/the-noble-art-of-maintenance-programming/)によればメンテナンスプログラマは用務員さんみたいに思われている…と当時から書いてありますね)
あんまりアツいんで**皆さんとアツさを共有したくて**翻訳しました。

なおQiitaの[CentOS + Erlang + Elixir + PhoenixのDockerイメージで今日から始めるElixir on Phoenix入門](http://qiita.com/xtity/items/969eefb83fcac9023542)の追記のところでも紹介されていましたので既に読んだよという方も多いかもしれません…。

------

　

*背景: 私は過去6年間を* **Ruby** *と* **Rails** *フレームワークでウェブアプリケーションの開発に費やしてきました。新しい言語が出てくるたびにちょっと粉をかけて来たのですが、* **Elixir** *は初めてグッと来た言語でした。*

# **Rubyがぶっ壊した!**

**Ruby**言語と**Rails**フレームワークはそれまでのウェブアプリケーションの開発手法を完全に変えてしまいました。それはコミュニティが気にかけていたように"価値の宗教"としての始まりでした。そして「プログラマが使うツールは開発者の幸福と生産性に向けて最適化されたものであるべきだ」という思想の嚆矢となりました。

「開発者が彼らのコードが十分にテストされ動作することを確認する」ということを開発者自身の仕事にするということは大きな挑戦でした。他の言語及びフレームワークからはそのやり方は笑いものにされていました…それが成功し始めるまでは。
そしてそういった言語・フレームワークも**Ruby**コミュニティからその原則を取り入れ始めるようになったのです[^1]。

![ガンジー150527.png](https://qiita-image-store.s3.amazonaws.com/0/46294/9621a7ec-d26d-8e8e-1e27-5c5ec24755df.png)

[^1]: テストファーストなどの考え方は別にRuby on Railsの専売特許ではないと思うのですが…普及時期はかぶりますし積極的にRailsに仕組みが取り入れられていたのは事実ですけど。

**Ruby**が人目につかない言語として控えめにスタートを切ったところから始まって最も人気のある言語のひとつになった大きな理由は**Rails**フレームワークとDHH[^2]、Wycats[^3]、Aaron Patterson、José Valim他の数多くのスーパースターたちによる驚異的なリーダーシップにあります。

[^2]: David Heinemeier Hansson。言わずと知れたRailsの原作者。
[^3]: Yehuda Katz。 RailsだけではなくjQuery, ember.jsなどの開発コアメンバー。
# **でも時折Rubyの控えめな出自の痕跡が現れる**
## メモリが足りない! ##

Zed Shawは悪名高い"[**Railsは[ゲットー](http://ja.wikipedia.org/wiki/%E3%82%B2%E3%83%83%E3%83%88%E3%83%BC)だ**](http://harmful.cat-v.org/software/ruby/rails/is-a-ghetto)"という投稿で、彼は初期のRailsにはガーベージコレクションにひどい問題があってアプリを動かし続けるためには4分に1度プロセスの再起動が必要だった！と喚き散らしています。

現在出ているうちで最も人気のあるrailsサーバーのひとつは[**Unicorn**](https://github.com/blog/517-unicorn)でしょう。私の本番のウェブアプリケーションはRailsアプリケーションで、今までやってきた他のアプリケーションと比較してもまずまず単純です。私はそのアプリケーションを[**DigitalOcean**](https://www.digitalocean.com/)の512MBのDroplet[^4]に標準的な説明書に従って移行しました。デプロイから数日経つと私のunicornサービスはメモリを食いつぶしアプリケーションは相当遅くなってしまいました。

[^4]: DropletはDegitalOceanの用語でバーチャルマシンのこと。下に**月5ドルの**、とあるので一番安い、512MBメモリ/2～3GHzの1Core CPU/20GBのSSDのやつでしょう。

どうやって解決したかって？[**Unicorn-worker-killer**](https://www.digitalocean.com/community/tutorials/how-to-optimize-unicorn-workers-in-a-ruby-on-rails-app)です。それは以前からある解決策と言えるか微妙なシロモノです。

DigitalOceanのDropletはunicornワーカースレッド2本～これがリソースの大半を食ってましたが～と、Postgresデータベースと他のいくつかのアプリケーションを動かすことができました。要求時間もま、OKなんじゃない？ってことでその仕事は終わりました。

## 並行性！

何年もRailsアプリケーションを開発してきていますが**私は今まで本番のRailsウェブアプリケーションで一度たりとも新しいスレッドを立ち上げたことはありません**。Rails自体はスレッドセーフですが、私はJava, C++その他のオブジェクト指向言語で他のスレッドをガンガン使った時に「**ここは竜の巣だな…**」と気づいていたからです。

実際、mutexやsemaphoreやそういったものについて考えたくないんですよ。ある一つのスレッドを動かしている間に別の一つのスレッドを止めてっていうのはどう見ても本物の並行動作に見えません。加えて、そのコード、**絶対に**デッドロックを起こさないって言えますか？

テストはRubyコミュニティの中心的な話題ですが、ほとんどのRuby開発者はスレッドが基本的にテスト不可能なもので、再現不能なバグを生み出しやすいためにスレッドを使うのを避けているのです[^5]。
[^5]: さすがに**ここまで言うか？**と思いますが… Rubyの**Thread**クラスなどの低レベルレイヤーを直接呼び出さず次の段落に出てくるgemを利用するという意味でしょう。

私はと言えば大半の健全なるRuby開発者と同じように並列に処理を実行させるには[__sidekiq__](https://github.com/mperham/sidekiq)または[__resque__](https://github.com/resque/resque)を使います。[__Rails 2.2__](http://weblog.rubyonrails.org/2008/11/21/rails-2-2-i18n-http-validators-thread-safety-jruby-1-9-compatibility-docs/)からはスレッドセーフが追加されていますが[__Rails 4.2__](http://weblog.rubyonrails.org/2014/12/19/Rails-4-2-final/)には[**Active Job API**](http://qiita.com/ryohashimoto/items/2f8fd685920a5318def4)が追加されました。こっちの方が100万倍使い物になります。

しかしバックグラウンドジョブというのは、その名の通りバックグラウンドで実行されるのです。ミッションクリティカルな項目はメインプロセスに残り、結果が失敗した時に反応するようにするか、タスクが終わるまでトランザクションが失敗することなく完了することを保証しなくてはなりません。

## スピード!

私はワガママです。自分の時間が貴重です。1秒でももったいない！それが私がテスト実行時間を気にする理由です。[**真剣に時間をかけて**](https://www.youtube.com/watch?v=V7g9amBX92A)テストスイートのパフォーマンスを最適化しました。アプリケーションの構造を変えることなく、テストによって引き起こされる設計へのダメージなしに、です。

以前仕事していたプロジェクトではユニットテストと機能テストに20分以上！もかかっていました。その時はRailsの分散テストフレームワークとしてhydra[^6]を使っていたのですがテストスイートがパスするまでが大変でした(おそらく不快なほど複雑なコードベース…中にはそれほど出来の良くないコードも含まれてそうな…が原因で)。
[^6]: 既に開発終了、今は[**gorgon**](https://github.com/nulogy/Gorgon)に引き継がれています。

テストが開始するまでの時間ですら相当長くかかります。だいたい40秒ぐらい。…で40秒経ったところで"_syntax error, unexpected end-of-input, expecting keyword_end_"などとメッセージが出て文法にポカミスがあったことがわかる、というわけです。

どうやって解決したかって？[**Zeus**](https://github.com/burke/zeus)です。Railsアプリ起動時の一般的なあれこれを事前にロードしてくれる素晴らしいgemで、(Githubの記述によれば):

    どんなRailsアプリも1秒以内に起動する

とのこと。私はこのgemがお気に入りですしRails開発者ならぜひ使うべきだと思います。

しかしZeusの開発者たちがどうやってこの機能を成し遂げたかというと…コア部分はイケてる**Go**で書いてあるんだなこれが…。

## Scala

この2年ほど、私は**Scala**を使ってみたくてウズウズしていました。いざ使い始めてみたら…速攻でイヤになってきました。

**Scala**には数多くの関数型プログラミング的な考え方が入っています。[**Akkaフレームワーク**](https://github.com/akka/akka)は非常に並行性が高く耐障害性を持つアプリケーションの作成を可能にします。**JVM**上で実行されるのでどんな**Java**のライブラリでも問題なく使えますし、JVMはパフォーマンスについてとんでもなくカリカリにチューニングされているのです。

Scala言語そのものはなかなか楽しめるもので、私はパターンマッチングが好きですね。じゃ、何が台無しにしたのかというと…**JVM**でした。**Jar**のパッケージマネジメントは**Rubygem**や**Bundler**と比べると控えめに言っても冗談抜きでややこしい。

解決法はいろいろとあります。例えば**SBT**、**Maven**、**Ivy**など[^7]。でもそれらで他の誰かが作ったライブラリをインポートしようとすると萎縮しちゃうんですよね…。多分私はRubyに毒されちゃってるんでしょう。でもRubyのパッケージ管理機構は私の生産性の核なのです。
[^7]: 同じJVM言語でも**Clojure**の**Leiningen**はかなりイケてると思います。以前の投稿でも述べましたが**Elixir**の**mix**と設計思想が似ています。

もうひとつScalaで悩ましかったのは使っていたライブラリの大部分がJavaで書かれており、それらを書いた人のスキルは私のスキルと根本的に違っていたということです。

Scalaで**Play!フレームワーク**を使ってWebのソリューションを構築するのはJavaで**Play!フレームワーク**を使ってWebのソリューションを構築するように感じられました。多少マシな文法とパターンマッチングの機能を除いては。**Play!**はRailsの影響をちょっとだけ受けているようですがその違いは理屈で説明できるようなものじゃないんです。

## Elixirのエコシステム

### **mixによるパッケージ管理**

Elixirを使っての「初めての冒険」で**Mix**に出会いました。MixはrubyのBundlerとrakeのハイブリッドみたいなものです。Mixを見てぶっ飛んだのは…**Bundlerとrakeに比べて悪くないじゃないか**ということでした。どっちよりも優れている、とは見えなかったけれどもともとハードルは高いし出会い自体は印象的でした。

Mixは粛々と作業を進めてくれるし、余計なことに口を出さないし、あなたにXMLとの格闘を押し付けたりもしないんです。

### **Erlang仮想マシン**

Elixirは**Erlang仮想マシン**上で走るのでErlangコミュニティのほとんどの優位性を取り込んでいます。ElixirもErlangも耐障害性と高いスケーラビリティを持つ関数型プログラミングがすごい！というところがご自慢です。

ElixirについてYouTubeで見られるトークのほとんどでErlangに関する次のような話が出てくるでしょう。

* Erlangは電話網の50%を動かしています。「この電話はメンテナンスのために計画停止します」なんて聞いたのはいつのことでしたっけね？
* 何億ドルかで買収された**WhatsApp**は何百万個ものプロセスを1台のサーバーで走らせ4億5千万ユーザーをサポートしていた。たったの32人のエンジニアで。

この優位性と同じタイプの優位性はElixirコミュニティにも取り込まれています。このため、ElixirのエンジニアがErlangで書かれた管理ツールや[**cowboy http**](https://github.com/ninenines/cowboy)サーバーを使っても自分の得意なことを犠牲にしなければならない、とは感じないはずです。

### **Phoenix Web フレームワーク**

[**Phoenix Web フレームワーク**](https://github.com/phoenixframework/phoenix)は明白にRuby on Railsに強く影響されているしPhoenixウェブアプリケーションを書くのはRailsアプリを書くのとすごく似ていると感じます。私はRailsのルーターが好きです。ActionControllerもActiveRecordもRails Viewもコードの書き方のお作法そのものも。私はRailsアプリケーションの構成も気に入っています。

PhoenixはそういうRailsっぽいソリューションなのでRailsアプリを作ってるような気分になるかもしれません。ただしElixirで動いていてElixirとErlang仮想マシンの利点を全て持っている、という点を除いて。

Phoenixは更に**WebSocket**もチャンネルを通じて提供しています。これで[**Firebase**](https://www.firebase.com/)[^8]が提供するような使いやすさともっと細かい粒度の制御でWebSocketを使うことができます。

[^8]: チャットなどのリアルタイム性の高いアプリ用のバックエンドを提供するサービスで昨年Googleに買収されました。Angular2の**ng2015用デモ**(todos)にも使われていたんですが、あれ、動かしてみてうっかり恥ずかしい内容(**心がぴょんぴょんするんじゃあ**とか)書いちゃった人いませんか？丸見えですからねw

「速い」ということは既にお伝えしましたっけ？Phoenixは電光石火の速さなんです。私の月5ドルのDigitalOcean dropletから拾ったこのログを見てください。シングルコアのマシンでリクエスト応答速度がほんとにマイクロ秒単位なんですよ[^9]。
![1-O8sLJiIZ0Ny5A53cIHBLwQ.png](https://qiita-image-store.s3.amazonaws.com/0/46294/805aa26c-c43c-dbfe-08f7-9ea5b7f33e02.png)
[^9]: 確かにMicrosoft AzureのもっとショボイVMでも```[info] Sent 200 in 934µs```とかチラ見えします。サンプルプログラム程度だとブラウザで開いた体感ではピンと来ないというのが正直なところですが。

### **強力なリーダーシップ**

私見ですが、単なるオープンソースと**ムーブメント**の違いはプロジェクトに関与するリーダーシップの周辺にあると思います。本当にデキる人たちが日夜ソフトウェアの改良に勤しまないとダメなんです。

Railsムーブメントは本当にものすごい加速度を持っていました。それはDHH、Aaron Patterson、José Valim、Wycats、その他たくさんの素晴らしい人たちの努力の賜物です。Railsが第一宇宙速度で発射されなかったら、人々はその仕事をするのをやめてしまったでしょう。

[それは古き良き、仕事に打ち込む際の心構えですし](http://instagram.com/p/yJ5JskI-ZK)、同時に[コミュニティを作るということは努力を要するのです！](https://instagram.com/p/yXrMS-I-V9/)[^10]
[^10]: ここの訳はあんまり自信ありません。リンク先のインスタグラムもなんかよくわかんなかった^_^;

Elixir言語のコアチームのJosé Valim、Chris McCord他全てのメンバーとPhoenixコアチームはこれまでも、そしてこれからもElixirコミュニティが成長するために不可欠な努力を続けていくでしょう。

# **ウェブの世界はまさに抜本的な変革を経験しようとしている**

その事実に向き合ってください。CRUDなアプリは既にコモディティ化しています。次に来るのは…_AirBnBみたいな感じでケチャップを借りるようなサービス_というのは生き残れない世界です。

勝つのは技術の変化を受け入れていくような人々です。Phoenix/ElixirのWebSocketやプロセス、及び並行性は開発者の幸福をなんら犠牲にせず簡単に使えるという事実はゲームのルールを完全に変えてしまいます。

私はRuby on Railsが大好きです。Railsは2005年から2014年までの間、人々がウェブアプリケーション開発について思っていたことをすっかり変えてしまいました。

私はElixirとPhoenixが同様の衝撃を2015年から2025年までに与えるのではないかと期待しています。

~~もし、あなたがPhoenixとElixirによるウェブアプリケーション開発を始めたいと思ったなら私が作った[**このチュートリアルをチェックしてください**](http://phoenix.thefirehoseproject.com/)[^11]~~

[^11]: で、私は赤いカプセルを飲んでしまったので今読み始めています…なかなか手順が細かく書いてあります。PhoenixってまだPostgresqlしか使えないんですね。あーなんかPostgresqlの設定に失敗したあ…(T_T);お手軽にsqlite3も使えたりしないだろうか…→2015/5/29 追記 現在、[**MySQLには対応しています**](http://www.phoenixframework.org/v0.13.1/docs/ecto-models)。

**2015/5/29 追記** 既にチュートリアルは古いようです。[**Phoenixの本家サイト**](http://www.phoenixframework.org/v0.13.1/docs/overview)を見たほうがいいです。