書籍紹介「プログラミング Elixir」

書いた人:ささだ

書籍紹介「プログラミング Elixir」

ソフトウェア開発の背景となるトレンドが変化するとき、新しいツールや新しいライブラリが求められます。マルチコアやクラウド環境が当たり前になった昨今、過去のどの時代よりも並行分散実行に対する要求が高まっています。Railsコアコミッターの一人であるJosé Valimによる、そのトレンドへの解答がElixirです。

私自身も José から「新言語を考えているんだ」とその文法に関する相談を受けたことがあります。Rubyの文法とRailsの柔軟性とErlangの並列分散性能の結実であるElixir、言語設計者がどんなことを考えながらElixirを作ったのか想像してみるのも楽しいでしょう。

まつもとゆきひろ

この本は、関数プログラミング言語というものに興味はあれど、畏れに二の足を踏むプログラマに優しい本です。わたしにとって、とても素敵な本だった、という意味です。もちろんこの一冊だけで関数プログラミングがどういうものかは分かったりしませんし、Elixir を自分の手足のように使うのもまだまだ遠い道のりです。けれど、少なくとも「プログラミングを変換で考える」という言葉の意味は読む前より分かるようになりました。パターンマッチをフィルタにする発想は魅力的で今すぐ使いたくなりましたし、プロセスを山のように生成してエラーを別のプロセスに監視させる仕組みは刺激的でした。再帰を書くのがちょっと得意になりました。

つまり、プログラミングについて、新しい考え方、切り取り方、前より広い視野を持つことができたのです。それから、Elixir が好きになりました。この本の狙いどおりです。翻訳という形で関わることで、平易で実際的な語り口で、「考え方」を紹介してくれるこの本を、じっくり読むことができたのは幸運でした。さらに、この本を裏打ちするコンピューター科学の学識について、笹田にしっかりと理解を助けてもらえたのも、すばらしい体験でした。この魅力的な本の日本語版を、みなさまの元にお届けできることを嬉しく思います。

鳥井雪(訳者)

最近、出版から足を洗うと表明(Pragdave 2.0)した Dave Thomas による最新の本、 Programming Elixir 1.2 を、笹田と鳥井により英語から日本語に翻訳した「プログラミング Elixir」が 2016/08/19 にオーム社から出版されましたので宣伝させて下さい。

Dave Thomas と言えば、Andy Hunt とともにピッケル本 を執筆し、 Ruby を世界に紹介した人物として Rubyist には有名(だと思う)ですが、最近(ここ数年)はプログラミング言語 Elixir にはまっていたようです。そして、Elixir 伝道師として書いたのが 2014 年の末に出版された Programming Elixir です。Elixir 1.0 をベースに執筆された本になります。Dave がどんだけ Elixir にはまってるんだ、というのは、本書を読むとよくわかります。多分、まだ大好きなんだろう、Ruby を意識した文章もありました。

訳書「プログラミング Elixir」は、この Programming Elixir を、笹田と鳥井で(のんびり)訳していたのですが、2016年1月に新しい版 Programming Elixir 1.2 が出版されてしまったので、そちらをベースに翻訳しなおしています。だいたい、2015年の年末に Programming Elixir の翻訳が終わったあとだったので、2016年正月に Programming Elixir 1.2 が出版され、呆然としたことを覚えています(大げさ)。泣きながら、diff を見て(原著は svn で管理されている)、訳文を update していきました。延々と手でパッチを当てていく作業…。そういうこともありましたが、多くの方にレビューをして頂き、無事 2016/08/19 に出版されることになりました。

そんなこんなで、無事に出版されることになったんだけど、最近 Elixir 1.3 に対応した Programming Elixir 1.3 が出版されるということで、もうこれはしょうがないのかな、という感じです。1.2 から 1.3 の修正は、(言語仕様の update を見るに)多分そんなに無いんじゃ無いかな、と思うんで、ぜひ買って下さい。元気があれば、1.2 -> 1.3 の diff をかみ砕いて紹介するコンテンツを用意しようと思います。

プログラミング言語 Elixir

本の説明をするよりも前に、プログラミング言語 Elixir とは何か、という説明が必要かもしれませんね。 「本書を買ってくれれば全てわかります!」ということなんですが、少しご紹介しますと、 Rails コミッタだったり、Ruby Hero だったりした José Valim が開発した言語で、 Erlang の VM である BEAM 上で動くスクリプト言語です。Erlang の構文は、Prolog 由来の独特な文法ですが(Rubyist のための他言語探訪 【第 10 回】 Erlang)、 Elixir は(ブロックが end で終わる、くらいの意味で)Ruby みたいな構文にした Erlang、みたいな言語です。 Rubyist には読みやすい言語なんじゃないかと思います。少なくとも、私には Erlang よりもずっと読みやすかったです。

Erlang には色々特長がありますが、その良さを Elixir はなるべくそのまま受け継いでいます。 具体的には、関数プログラミング(一級関数、パターンマッチ、不変データ、リストやタプルといったデータ型、などなど)、 アクターモデルによる並行プログラミングサポート(軽量なプロセス、頑強な並行プログラミングをサポートするための OTP というライブラリ群、イベント監視、などなど)、 マクロやゆるい型システム(Dialyzer)などが使えます。 さらに Elixir 独自の機能として、独自のモジュールシステム(ビヘイビアやプロトコル)などを備えています(あまり私は Erlang を知らないので、もしかしたら Erlang にもあるのかもしれないけど…)。 なんというか、とてもモダンな言語です。

具体的なプログラム例です。

 # Ruby
 puts "Hello, World!"

 # Elixir
 IO.puts "Hello, World!"

Hello world は、まぁ、Ruby とほとんど同じですね。本書の冒頭で紹介されている、少しそれっぽいプログラムをご紹介してみます。

defmodule Parallel do
  def pmap(collection, func) do
    collection
    |> Enum.map(&(Task.async(fn -> func.(&1) end)))
    |> Enum.map(&Task.await/1)
  end
end

このプログラムでは、Parallel というモジュールに pmap という関数を定義しています。 pmap は、与えられたコレクションに対して map(Ruby での Enumerable#map と同じようなものと考えて下さい)を行なうのですが、 各要素の処理を、要素数の分だけプロセスを生成し、各プロセスで並行に実行する、というものです。 ちょっと見ても、よくわからないような気がしますが、大丈夫、本書を読めば、わかるようになります。

プログラミング言語の文法も、最近の言語っぽく、他の言語の良いところを導入しながら Erlang の良さを残すような、使いやすいものになっていますが、さらに、エコシステムが充実しています。 Rubygems や Bundler のようなものが標準でついてきており、テストの記述もらくらくにできるようになっています。 José Valim が Rails などでの良い文化を取り入れたんじゃないかなと思います。あと、ドキュメントも豊富ですね。

さらに、Phoenix framework というウェブアプリケーションフレームワークがあり、まさに Rails のレイヤのソフトウェアも存在します(本書では、Phoenix framework については紹介していません)。

Programming Elixir

Programming Elixir では、Elixir の言語紹介をしていますが、文法や関数リファレンスではありません(Dave 自身、それを文中で明確に否定しています)。 その代わり、Elixir にはどのようなプログラムがあり、どのような考え方で Elixir プログラムを書いていけば良いか、 そして、ツールを使ってどのようにプロジェクトを進めていけばいいかをしっかりと解説しています。

Elixir の根底にある、関数プログラミングの考え方を、とても丁寧に解説していますので、その方面に不案内な方や、興味がある方にもオススメできると思います。むしろ、そのために買ってもいいかも?

プログラミング Elixir

そういう良さそうな本の訳書である「プログラミング Elixir」には、原著にはなかったおまけがついています。日本語版読者に向けて、José と Dave になんか書いて、ってお願いしたら、凄くいい文章をすぐに寄せてくれました。彼らは筆が早いですね。付録として巻末に掲載してあります。

あ、あと関連するイベントを企画頂いているようですので、興味があればチェックしておいて下さい。

以下、目次とちょっとした解説です。

第1章  赤いカプセルをとれ
 要するにイントロです。
 タイトルはマトリックスからですね。

第I部  伝統的なプログラミング
 第I部では、並行制御以外の、基礎の部分を紹介しています。

第2章  パターンマッチ
 Elixir の特長のひとつである、パターンマッチについて紹介しています。
 a = 1 は、代入文じゃなくてパターンマッチ文になります。面白いですよね。
  例えば 1 = a は true になります(ただし、a = 1 を先にやっていれば)。

第3章  不変性
 基本的に、Elixir(というか Erlang)では、扱うデータはすべて不変データです。
 Ruby でいうところの freeze されたオブジェクト、という感じです。
 この章では、「それってどういう意味?」ってのを丁寧に説明しています。
 並行プログラミングで、とくに有利なんですよねぇ。

第4章  Elixirの基礎
 基本データ型とか、そういうやつを紹介しています。

第5章  無名関数
 いわゆる lambda ですね。fn x -> x + 1 みたいに書きます。

第6章  モジュールと名前付き関数
 モジュールの書き方とか、名前付き関数の書き方、とか。
 関数のパラメータにパターンマッチが書けたりします。

第7章  リストと再帰
 リストデータ構造がなんで大事か、そして再帰プログラミングがなぜ凄いか、
 みたいな話です。

第8章  マップ、キーワードリスト、セット、構造体
 よりリッチなデータ構造の紹介です。マップは Ruby でいう Hash みたいなものです。

第9章  寄り道:型とは何か?
 あんまり深淵な話じゃなくて、プリミティブデータ型と、よりリッチな型(複合データ型)の違いはなんだろね、
 みたいな話です。

第10章 コレクションの処理―――Enum とStream
 Enum は Ruby でいう Enumerable、ストリームは Ruby でいう Enumerator::Lazy に相当するものです。多分。
 あ、あと内包表記についての解説があります。便利ですよね。

第11章 文字列とバイナリ
 Rubyist には馴染み深い文字列の話です。

第12章 制御フロー
 パターンマッチとかあるんで、あんまり要らない if などの制御構文の話です。

第13章 プロジェクトを構成する
 第I部の山場、実際に意味のあるプロジェクトを作ってみよう、という話で、
 GitHub から Issues 一覧を取ってくるプログラムを書いてみよう、というのを、
 ツールを駆使しながら実際に書いていきます。
 実際のプロジェクトがそうであるように、テストやドキュメントまで書きます。

第II部 並行プログラミング
 Erlang といえば並行プログラミング、みたいなところがありますが、
 ここではその話をします。

第14章 複数のプロセスを使う
 プロセスとは何か、生成するには、同期するには、監視するには、みたいな話です。

第15章 ノード―――分散システムの要
 Elixir のプロセスは、マシンをまたいでも通信できるんですが、
 それをノードという形で抽象化しています。その紹介をしています。

第16章 OTP:サーバ
 Erlang の並行処理をロバストにするためのライブラリとして(多分)よく知られているのが OTP です。
 私はこの OTP を勉強したくて翻訳を始めました。
 Elixir は OTP をサポートしますが、まずは GenServer というものの紹介。

第17章 OTP:スーパーバイザ
 プロセス監視をどうやって行なうか、という機能を提供する OTP スーパーバイザの紹介です。

第18章 OTP:アプリケーション
 OTP (か Erlang)の世界では、アプリケーションというのは機能のまとまりで、DLL みたいなものらしいです。
 で、それをどうやって構成し、実際にデプロイするか、みたいな話。

第19章 タスクとエージェント
 OTP を直に触るとしんどいので、それを使いやすくした Task と Agent という機能の紹介です。

第III部 より高度なElixir1
 なんか高度な機能について紹介しています。

第20章 マクロとコードの評価
 いわゆるマクロです。

第21章 モジュールのリンク: ビヘイビアとuse
 ビヘイビアという言語機能の紹介です。

第22章 プロトコル―――ポリモーフィック関数
 プロトコルという言語機能の紹介です。

第23章 かっこいい機能いろいろ
 落穂拾いの章です。

付録A 例外:raise、try、catch、throw
 Elixir(というか Erlang)では、例外が起きたらプロセスごと殺す
 (その代わり、再起動をちゃんと出来るようにしておく、それにより、エラーの影響範囲を小さくする)、
 という文化なのだそうですが、一応例外処理機構もあるよ、ということで紹介しています。

付録B 型仕様と型チェック
 Elixir では、ほぼドキュメントとして型を付けたり付けなかったりすることができるんですが、
 その辺の話を紹介しています。

付録C 参考文献
 参考文献。ただし1冊。

付録D 日本語版に寄せて
 日本語版特別(?)付録です。

良かったら買って下さい。 使う、使わないに限らず、新しい、しかも筋の良い言語の紹介を見るのは面白いですよ。

翻訳動機

そもそも、なんで Ruby インタプリタを開発している笹田が翻訳をしたのか(鳥井は笹田に巻き込まれました)、ということですが、訳者後書きに書いてあるので読んでもらうとして、とりあえず Elixir は良さそうだな、これは勉強しなきゃな、ということでした。要するに、並行制御勉強したかったんですよ。