Hatena::ブログ(Diary)

あどけない話

2011-10-13

書評:Scala スケーラブルプログラミング 第2版

Scala の作者である Odersky らが書いた「Scala スケーラブルプログラミング」の第2版が出版されました。

Scalaスケーラブルプログラミング第2版

Scalaスケーラブルプログラミング第2版

僕は Haskeller で Scala は初心者です。その僕から見て、この本は本格的で良質な関数型言語の入門書に仕上がっています。特に、関数型言語を学びたい Java プログラマーに、この本をお勧めします。

この本は分厚いので、敬遠したくなるかもしれませんが、それぞれの章は小さくまとめられており、内容もこなれています。訳もよいので、案外すらすら読めると思います。

静的型付けの利点

記述が冗長でエラー検出率の低い Java の型システムを使うと、静的型付けが嫌になり、動的型付けの言語に流れていく人も多いようです。しかし、動的型付け言語ではコンパイルによる型検査がないため、安全性を高めるにはたくさんのテストを記述する必要があります。

もし、記述が簡潔でエラー検出率の高いシステム型があるとすれば、それが理想的だと思う人もいるでしょう。まさにそれが、静的に強く型付けされた関数型の型システムです。Scala もこの型システムを継承しています。Scala では、命令的にも関数的にも書くことができ、命令的に書くと型システムの威力は半減しますが、関数的に書くと型システムの力を引き出せます。

とにかく1.3.4節を読んで下さい。すべてのプログラマーは、立ち読みでもいいので、1.3.4節の型システムに関する説明を読むべきです。

再帰

何が関数型なのかという共通理解はありません。僕の関数型の定義は、「永続データプログラミングを奨励していること」です。永続データプログラミングとは、破壊できない、つまり再代入不可能なデータを使ったプログラミングです。Scala では var ではなく、val を使うことになります。

val しか使わない場合、自ずと繰り返しは(初等的には)再帰で実現することになります。この本では突然再帰を説明するのではなく、まず Java の命令的な繰り返しのコードを見せ、Scala の命令的なコードに変換し、さらに関数的な再帰のコードに変換するという手法を採っています。こうやって順を追って説明してもらうと、再代入がないプログラミングの方法がすんなり頭に入って来るのではないでしょうか?

再帰を使うと、スタックが溢れてしまうと心配する人もいるでしょう。しかし、末尾再帰という方法で再帰関数を書けば、コンパイル時に再帰部分がジャンプ命令に置き換えられるので、スタックは溢れません。この本がすごいのは、実際にループで実現した関数と末尾再帰で実現した関数とが、同じバイトコードを生成するのを実例で示しているところです。

リストプログラミング

永続データの代表選手はリストです。この本では「リスト操作」の章で、リストの基本から、高階関数を使ったリスト操作まで、広く浅く触れられています。ぜひ、ここで紹介されている関数のソースを探して読んでみて下さい。永続データプログラミングでは、関数をどのように実装するのかが分かるでしょう。

また、Scala の一風変わった for も、N-queen 問題を通じて解説されます。この本にははっきりとは書かれていないとは思いますが、Scala の for は、実はリスト内包表記であり、Haskellモナドと同じものです。仰々しい名前を用いずに、単に for と名付けてしまう大胆さに敬服します。

コンビネータ

関数型言語を学ぶなら、ぜひたどり着いてほしいのがコンビネータという考え方です。コンビネータとは、素敵な内部DSLのことで、この本ではその一例としてパーサーコンビネータが紹介してあります。あれほど苦労したパーサーも、パーサーコンビネータがあればとるに足らない問題になります。ぜひこの章までは頑張って読んで下さい。

ネタ

第1版の表紙にはコップが1つ描かれていましたが、第2版では2つになってスケールアウトしたそうです。