書評：プログラミングElixir第2版

# はじめに

2020年12月1日に発売された「__プログラミングElixir 第2版__」をさっとですが読みました。
その書評を書きます。

また、本記事は [Elixir Advent Calendar 2020](https://qiita.com/advent-calendar/2020/elixir)の12日目の記事でもあります。

##  補足: Elixir Advent Calendar 2020について

11日目の記事は、@pojiro 氏の「[Elixirで並行コマンド実行サーバーを作ったら感動した話](https://qiita.com/pojiro/items/050da725dde4d05fed9e)」でした。

なお、次の13日目は @Sadalsuud さんが担当されます。お楽しみに。

# 書籍の概要

「__プログラミングElixir 第2版__」は、__Dave Thomas__（デイブ・トーマス）著[^DaveThomas]の「Programming Elixir 1.6（Pragmatic Bookshelf, 2018）」[^ProgrammingElixir1.6][^Bookshelf]の__日本語訳__本です。

<img width="50%" alt="プログラミングElixir 第2版" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316636/1ef404a2-87b2-f041-0650-41212febacb0.jpeg" >

[^DaveThomas]: 他の著書として「達人プログラマー」や「プログラミングRuby」（通称ピッケル本）があります。アジャイルソフトウェア開発宣言の著者の一人でもあります。

[^ProgrammingElixir1.6]: https://www.oreilly.com/library/view/programming-elixir-16/9781680506129/
[^Bookshelf]: https://pragprog.com/titles/elixir16/programming-elixir-1-6/

訳者は、__笹田耕一__氏[^sasada]と__鳥井雪__氏[^torii]です。

[^sasada]: フルタイムRubyコミッター。未踏ユースのスーパクリエイターの肩書きも持つ。
[^torii]: 他の訳書に「ルビィのぼうけん」シリーズがあります。

本のサイズは__B5変__、ページ数は__424頁__となっています。

出版社は__オーム社__です。
オーム社の書籍紹介ページは以下となります。
https://www.ohmsha.co.jp/book/9784274226373/

第1版は2016年に発行されています。
この時のEliixirのバージョンは1.2でした。
4年の年月を経て、第2版が出版されました。
（なお、原著の発行は第1版が2014年、第2版が2018年です。）

第2版は第1版と比べると、一回り大きくなっています。
<img width="50%" alt="プログラミングElixir 第2版と第1版の比較" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316636/8be20b90-0a73-d312-30e3-059e4ec55bdf.jpeg" >

また、本書は全ページがカラーで印刷されています。
そのため、重要な単語、ソースコード、コンソールの実行結果、イメージ図、コラムなどが見やすいです。

それと、前述にもありますが、本書で扱っているElixirのバージョンは1.6がベースです。
Elixirの最新バージョン[^elixir_version]とのギャップはありますが、Elixir自体は文法や標準的な機能は下位バージョンとの差異が少ないです。
そのため、最新バージョンを利用する際にでも十分参考となります。
もちろん、1.6以降の後続バージョンにより追加された機能にについては記載されていませんが、訳者や付録などで一部の情報はフォローされています。

[^elixir_version]: 2020年12月12日時点の最新バージョンはv1.11.2である。https://github.com/elixir-lang/elixir/releases


----

本書はリファレンス本ではありません。
どのような思想でElixirのプログラムを書いていけば良いかを解説しています。

その思想は、本文中でも度々提示されています。

_「1.6　Think Different(ly)」からの抜粋：_
> この本は、考え方を変えることについての本だ。

_「19.4　自分のElixirアプリケーションを計画しよう」からの抜粋：_
> この本は、考え方を変える本だ。私たちの各コードと、不変のデータとともにる関数のスタイルが、いかに私たちに変換の観点から考えることに集中させてくれるか、について考えるところから始めた。

_「25.3　お楽しみはこれからだ！」からの抜粋：_
> この本はElixirを網羅するものではない。ハイライトを取り上げて、Elixirでアプリケーションのコーディングを始めるのに十分な情報を提供しようとするものだ。

結果として、Elixirというプログラミング言語がどのような思想で作られており、これを理解するためにどのような思考をすれば良いかを本書は教えてくれます。

また、本書では本文を読むだけにとどめず、"__手を動かす__"ことも推奨されています。
書かれている内容を写経し、章末の練習問題を実施する。
さらに疑問に思ったことを調査して解いてみる。
それが、Elixirと親しむための出発点であるとDave Thomas氏は主張しています。

## 本書の想定読者

書籍自体には書かれていませんが、オーム社の紹介ページでは想定読者として以下が挙げられています。

- 向上心のあるプログラマ
- Elixirに興味のある人
- Rubyユーザ
- Erlangユーザ
- プログラミングを学んでいる学生
- 情報系の大学生

ErlangとRubyが挙げられているのは、ElixirがErlangVMで動作することとRubyのような文法で書けることが関係していると想像できます。ErlangおよびRubyのプログラマ達が、次なる武器としてElixirを選択するのは学習コスト面から見ても良い選択でしょう。
また、学生が挙げられているのは、`未来のプログラマたちをElixirの誘惑に堕落させようとしている`ためと考えられます。[^yuwaku]

[^yuwaku]: 本書の「はじめに（正当化のむなしい試み、再び）」より。著者のDave氏がSouthren Methodist University の非常勤講師であることが関係していると考えられる。

なお、私自身は、__ビギナー／ベテランを問わず、Elixirを使っている人__全員も想定読者であると考えております。


## 目次

部と章を以下に記載します。
節のタイトルまで知りたい場合は、[こちら](https://www.ohmsha.co.jp/book/9784274226373/#tab2)を参照ください。

- Elixir作者による前書き
- はじめに（正当化のむなしい試み、再び）
- 第1章　赤いカプセルをとれ
- 第 I 部　伝統的なプログラミング
    - 第2章　パターンマッチ
    - 第3章　不変性
    - 第4章　Elixirの基礎
    - 第5章　無名関数
    - 第6章　モジュールと名前付き関数
    - 第7章　リストと再帰
    - 第8章　マップ、キーワードリスト、セット、構造体
    - 第9章　寄り道：型とは何か？
    - 第10章　コレクションの処理 ── EnumとStream
    - 第11章　文字列とバイナリ
    - 第12章　制御フロー
    - 第13章　プロジェクトを構成する
    - 第14章　ツールの利用
- 第 II 部　並行プログラミング
    - 第15章　複数のプロセスを使う
    - 第16章　ノード ── 分散システムの要
    - 第17章　OTP：サーバ
    - 第18章　OTP：スーパーバイザ
    - 第19章　さらに複雑な例
    - 第20章　OTP：アプリケーション
    - 第21章　タスクとエージェント
- 第 III 部　より高度なElixir
    - 第22章　マクロとコードの評価
    - 第23章　モジュールのリンク：ビヘイビアとuse
    - 第24章　プロトコル ── ポリモーフィック関数
    - 第25章　かっこいい機能いろいろ
- 付録A　例外：rais、try、catch、throw
- 付録B　型仕様と型チェック
- 付録C　参考文献
- 付録D　Elixir 1.6以降の状況と開発運用の実際
- 付録E　日本語版に寄せて
- 索引 

## 第1版との差異（目次レベル）

目次レベルで、第2版と第1版を比較してみました。

### 章単位での追加

- 14章 ツールの利用
- 19章 さらに複雑な例
- 付録D Elixir1.6以降の状況と開発運用の実際[^drecom]

[^drecom]: 日本語訳本のみにある章です。

### 節単位での追加

- 4.6 日付と時間
- 13.5 リファクタリング：大きな関数注意報
- 17.6 サーバをコンポーネントにする
- 18.2 ワーカーの再起動オプション
- E.2 Elixir作者より（第2版発行に寄せて）

# 内容紹介

ここでは、"部"単位で、本書の内容紹介を行います。

なお、第1版のものですが、訳者である笹田氏が書かれた書籍紹介が"__るびま__"に載っていましたのでリンクを紹介しておきます。
https://magazine.rubyist.net/articles/0054/0054-ElixirBook.html

## 赤いカプセルをとれ

本書のイントロダクションです。
第I部に含めず独立した章として最初に持ってきて、本書全体を通した考え方を読者に提示しています。
上記に加えて、Elixirのインストール、REPLであるIExについての簡単な解説が書かれています。

本章を要約すると、以下の点が主張されています。

- プログラミングはデータを"__変換__"するもの。関数はデータ変換器。
- 手を動かして練習問題を解こう。
- プログラミングを楽しむことを忘れないで。

この章を読むことで、読者はElixirを学ぶ準備（または心構え）ができます。

### 余談：マトリックス

本章のタイトルは、映画『_マトリックス_』からの引用のようです。
作中、マトリックスの主人公は、次の2択を迫られます。
> You take the blue pill - the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill - you stay in Wonderland and I show you how deep the rabbit-hole goes. 

意訳すると、次のような意味になります。

「<font color="blue">青いカプセルを飲めばベッドで目が覚め今まで通り</font>」
「<font color="red">赤いカプセルを飲めば真実をみることができる</font>」

つまり、読者に「<font color="red">赤いカプセル</font>」を選択させ、Elixirの"真実"（この場合、新しい世界、もしくは困難だが未来につながる道）をみさせる、と考えられます。


## 第 I 部　伝統的なプログラミング

Elixirの基本文法について書かれている章がまとめられています。
ここでは、並行プログラミングやマクロなどの機能へ触れる前の基礎知識について知ることができます。
加えて、各章の練習問題を実施することで、その基礎知識を身につけることができます。

基礎知識なのでどれも大事ではありますが、第I部の中で特筆すべき以下の3つの章です。

- 第2章　パターンマッチ
- 第7章　リストと再帰
- 第10章　コレクションの処理 ── EnumとStream

`パターンマッチ`は、Elixirの最大の特徴です。
だからこそ、最初に出てきています。
逆説的に、パターンマッチを理解し使いこなすことが、Elixirを使いこなすことにもつながります。

つづいて、`リストと再帰`です。
リストはコレクション型の一つではありますが、専用の章が設けられるほど大事な要素です。
実際、Elixirのプログラム中ではこのリストが多く利用されるシーンを見ます。
リストの構造である`ヘッダ`と`テイル`の特徴を知り、関数や再帰にどのように当てはめていくかをこの章で確認できます。

最後に、`コレクションの処理 ── EnumとStream`です。
本章ではコレクション制御を学びます。そして、コレクション制御を行うためには、前述の`パターンマッチ`と`リスト`が大きく関係してきます。
また、タイトルにあるEnumとStreamは、Enumが逐次列挙、Streamが遅延列挙という位置付けです。
この二つを使い分けることで、Elixirのプログラミングに幅が広がります。

さて、`パターンマッチ`、`リストと再帰`、`コレクションの処理`が理解できると、「赤いカプセルをとれ」の章で挙げられていた「_プログラミングはデータを_"__変換__"_するもの_」が実感として理解できます。同時に、Elixirをプログラミングする楽しさがわかってきます。

実際、並行プログラミングを扱わないレベルの内容であれば、この3つの内容を多く使うことになります。

上記3点をピックアップしましたが、それ以外の章にも書かれている内容も大切です。
第I部は、ビギナー／ベテランを問わず、読み直すことが多くなる内容がまとめられています。

### 14章 ツールの利用

第2版から追加された章です。
この章では、デバッグ／テスト／コード探索／サーバ監視／コードの整形、について記述されています。プロジェクトを作成してある程度のコーディングを進めていった際に見直すことが増える内容と言えます。
以下、簡単にここの内容について記載します。

- デバッグは、IExを利用したデバッグのやり方が書かれています。ブレークポイント設置によるデバッグ方法に触れているので、より詳細なデータ内容の確認ができます。
- テストについては、テストのコメントの書き方、テストの構造化の方法、および特製テストについて書かれています。
- コード探索は、依存関係を確認する`mix xref`コマンドの使い方について書かれています。
- サーバ監視については、Erlangのサーバモニタリングツールの使い方が書かれています。
- コード整形は、整形ツールを起動する`mix format`コマンドの使い方について書かれています。

## 第 II 部　並行プログラミング

パターンマッチに並ぶElixirの特徴でもある__並行プログラミング__についてまとめられています。
並行プログラミングを扱うようになると、見直す機会が多くなるでしょう。

本章の説明は回りくどく書かれています。
Elixirがアクターモデルを採用していることの説明から始まり、独自に並行プログラミングを作成し、その後で分散システムを作ります。

さらにその後で、OTPについて触れ、Elixirのフレームワーク（PhoexnixやNervesなど）で馴染みのある`GenServer`や`Supervisors`について学んでいきます。
PhoexnixやNervesのコードを理解する際には、第II部の知識が必要となります。

第II部の内容を理解することで、Elixirに魅せられた多くの人々が感じたであろう__並行プログラミング__の恩恵を感じられるでしょう。

### 19章 さらに複雑な例

本章は、Elixirでの並行プログラミングにおける、_著者のアドホックなアプローチ_について書かれています。
その指針は以下の5つであり、本章の中で詳しい解説がされています。

- 環境は何で、その制約条件は何か？
- 明らかな関心の中心は何か？
- 実行時の特徴は何か？
- エラーから何を守るのか？
- どのようにこれらを実行するのか？

## 第 III 部　より高度なElixir

第I部と第II部は__使う側__の情報でした。
一方、第III部の内容は、__使わせる側__の情報となります。

それらは、__マクロ__であり、__use__であり、__プロトコル__です。

- マクロ: 言語の構文を拡張する
- use: モジュールに能力を追加する
- プロトコル: 既存のモジュールにビヘイビアを追加する

マクロについては、_必要時以外は使わないように_という原則を上げた後で、マクロの作り方が説明されているます。

また、useとプロトコルはある意味でセットの内容です。
useでは、自分の管理下にあるモジュールに対して、ビヘイビア（Javaのインタフェースに似た機能）で宣言された機能（や関数）を追加します。
一方、プロトコルは他者の管理下（すなわち、コードを直接編集できない）にあるモジュールに対して機能を追加します。
これら二つの機能の使い方が、それぞれの章で書かれています。

また、それ以外にも独自シジルの作成方法やアンブレラプロジェクトについても解説がされています。

- シジル: リテラルの代わりとなる文法
- アンブレラプロジェクト: 複数のアプリケーション／ライブラリを管理するプロジェクト

タイトルの通り、第III部は「_より高度なElixir_」を目指す際に読む内容です。
プロダクト開発時などでライブラリを提供する立場の人たちが主に目を通す内容となっています。

## 付録

例外処理、および型仕様／型チェックについて触れられています。
付録として載っているのは、これらの利用頻度が低いからです。

例外処理については、例外発生方法とキャッチ方法について書かれています。
しかし、Erlangと同様にエラーは致命的でプロセスの再起動の立場をとります。
そのため、言語仕様としてあるため説明はしたが、この付録内容は無視してくれというスタンスになっています。

型仕様／型チェックについては、Erlang由来の`-spec`と、型推論のツールであるDialyzerについて書かれています。Elixirは型についてはおおらかではあるが、厳密に型を制限したい場合もあります。よって、型のチェックが必要になった場合のために、本付録が用意されたと考えられます。
しかし、本付録も、_100%の型チェックを目指して時間を浪費しないように_、という言葉で締められています。

それ以外には、参考文献や著者／訳者／Elixir作者からのコメントが載っています。

特筆すべき点としては、日本語訳版の第2版のみ、以下の「付録D」が付与されています。

### 付録D Elixir1.6以降の状況と開発運用の実際

こちらの記事は、日本語訳版にのみ付いています。
Elixir1.0から本番環境で利用されていた、株式会社ドリコムの大原常徳氏（ @ohr486 ）による寄稿です。タイトルの通り、Elixir1.6以降の状況と開発運用に対してのフォローアップの内容となっています。

とくに「D.2 リリース」については、Elixir 1.9から組み込まれたリリース関連のコマンド`mix release`について触れられていますので、一見の価値ありだと考えます。

# 所感

Elixirでプログラムを組む人には、一度は目を通してもらいたいと思える一冊です。

Elixirは比較的年齢が若い言語でもあり、日本内での本番プロダクトでの採用事例も少ないです。それも関係し、使用者の人口も少なく、結果として日本国内での商業誌の数も少ない[^syoseki1][^syoseki2]です。
実際のところ、基本文法から並行プログラミング、マクロまで扱った日本語の商業誌書籍は、実質この一冊のみです。それも関係し、"定番の一冊"[^motironn]と言えるでしょう。

[^syoseki1]: 黒田努氏　「Elixir/Phoenix 初級」シリーズ
[^syoseki2]: 川邑リュウ氏　「Elixirへのいざない」（※拙著）
[^motironn]: もちろん、内容にについては秀逸であるからこその定番です。

書籍でなくても、公式ドキュメントや[Elixir School](https://elixirschool.com/ja/)、有識者によるQiitaなどのWeb記事もあります。
ですが、一冊の書籍となっていることで、まとまった知識を一度に得られることもできます。
Elixirをはじめた当初はWebコンテンツで学んでいたとしても、ある程度の知識が身についてきたと思えたら、是非本書を買って読んでみてください。より、Elixirの思想／実装の仕方が理解できます。

Elixirは『関数型』と『並行処理』というキーワードから敷居が高く感じられる人も多いかと思いますが、実は他の関数型言語と比較してとっつきやすい言語です。
加えて、無理に並行処理をする必要もありません。Elixir（正確には、そのベースとなったErlang）の軽量さを利用したシンプルなアプリケーションでも、十分にその恩恵を受けられると思います。
そして、それは本書の第I部までの内容（193ページまで）でまかなえます。



# まとめ

- 日本語で書かれたElixirの書籍としては、この本が定番。
    - ただし、各種のライブラリやPhoenixやNervesなどのフレームワークについては書かれていない。それらは、Web記事や別の書籍を参考にしてください。 
- 物理本はB5変版／424頁と、サイズ大きく且つページ数も多い。
- 大きく3部構成に分かれている。Elixirの基本／基礎、並行プログラミング、より高度な機能（マクロ／プロトコル／use）となっており、理解度に応じて読み直す際には重宝する。
- 2016年に出版された第1版から、いくつかの章が追記されている。
- Elixir 1.6ベースでの記述されているため、Elixir最新バージョンとはギャップはある。
    - ただし、Elixir自体は文法や標準的な機能は下位バージョンとの差異が少ないため、最新バージョンを利用する際にでも十分参考となる。
- 日本語訳版のみの「__付録D Elixir1.6以降の状況と開発運用の実際__」には、Elixir 1.6以降の情報がフォローアップされているので必読。特に、リリース箇所は一見の価値あり。

2021年、新しい言語を習得されるなら、本書を片手にElixirを習得するのはいかがでしょうか？
<font color="red">赤いカプセル</font>により、新しい世界が見えてくると思いますよ。

## 余談

今回紹介した「__プログラミングElixir 第2版__」ですが、訳者の笹田耕一氏のGitHibページ上で応募のあった[^oubo]「__書評用書籍プレゼントキャンペーン__」に当選して献本いただいたものとなります。
書評用にいただいたものですので責務を果たさねば、ということで書評記事を書きました。
ひとまず、責任を果たせたので良かったです。

[^oubo]: https://github.com/ko1/programming-elixir-1-6-ja#書評用書籍プレゼントキャンペーン