Subscribed unsubscribe Subscribe Subscribe

Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

書評『コーディングを支える技術』(西尾泰和・著)

西尾泰和さん (@nishio)の新刊『コーディングを支える技術』をご恵贈いただきました。ありがとうございます。

コーディングを支える技術 ~成り立ちから学ぶプログラミング作法 (WEB+DB PRESS plus)

コーディングを支える技術 ~成り立ちから学ぶプログラミング作法 (WEB+DB PRESS plus)

達人プログラマー―システム開発の職人から名匠への道』という本で、こんなことが述べられています(手元に現物がないので「総論 複数のプログラミング言語を学ぶ意義」から孫引き)。

毎年少なくとも一つの言語を学習する - 言語が異なると、同じ問題でも違った解決方法が採用されます。つまり、いくつかの異なったアプローチを学習することにより、幅広い思考ができるようになるわけです。

先日、この話を思いだして「今年は何をやろうかなー」と考えていました。「去年は仕事の関係でRubyPHPをあらたに使い始めたので、今年は〜」などといっていたところ、id:kazuhookuさんにはアセンブラをすすめられ、id:stanakaさんには言語を実装してみることをすすめられました。

アセンブラのすすめには、コンピュータそのものにできるだけ近づくことで得られる基礎的な知識が大事だという含意があるのでしょうし、言語の実装についても同様に、言語そのものの成り立ちから得られる本質を学ぶべきだということなのでしょう。尊敬する技術者ふたりがそろって、言語にとらわれない、どの言語にも共通する基礎の大事さを説いてくださったことに、感銘を覚えました。

本書は、そのような「言語にとらわれないどの言語にも共通する基礎」についての本です。

世の中にはたくさんの「プログラミング言語」があります。そのうちのどれが優れているのか、どれを習得するのが就職などに有利かといった議論も盛んです(だいたいフレームにしかなりませんが……)。それだけたくさんの言語をすべて学ぶことは不可能ですし、また、どれを学べばいいかなんて、この先どうなるか、未来を予見することなどできないのですから、それもまた不可能です。そこで本書は「言語に依存しない普遍的な知識」を学ぶことが重要であると説きます。

そこで本書の採る方法は以下のふたつです。

  1. 比較から学ぶ
  2. 歴史から学ぶ

どの言語も、それぞれの言語を開発した作者がいます。そして、それぞれに問題を抱え、それぞれに自分がよいと思った方法で解決を図ったからこそ、百花繚乱のいまがあるわけです。問題に対する異なった解決策こそが、各言語の文法や機能の差異であり、それを学ぶことによってプログラミング言語へのより深い理解に達することができるというのが本書の主張です。

また、プログラミングには既に半世紀を優に超える歴史があります。いまは当たり前に思っている機能も、それができた当初は新しい機能だったわけです。そのことをふりかえることで、いまある機能がなぜこのようにあるのかを知ることも、言語の理解を深めることにつながります。

「比較から学ぶ」について、一例を挙げます。「型」というものがなぜあるのかというのを示すのに、まず、数値をコンピュータでどのように表すことができるのかという説明から入ります。その結果、あるビットパタンがあったとして、それが実際には整数を表しているのか浮動小数点数を表しているのかは、そのビットパタンがなにを表しているかという情報 = 型がないと決定できないという基礎づけをした上で、Cにおけるtypedefから始まり、Javaにおけるインタフェイス、スクリプト言語の動的型付け、型推論まで一気通貫に、比較による説明を行います。

「エラー処理」の章では、Cにおける返り値でのエラー判定の問題点を紹介した上で、1959年のCOBOL、64年のPL/Iにおける原始的エラー処理機構の萌芽、1975年のGoodenough論文から始まる現代的なエラー処理の構文を紹介した上で、C++finallyがない代わりにRAIIパタンを使うことを作者のBjarne Stroustrupが推奨しているだとか、2001年のD言語におけるRAIIパタンを改善したscope(exit)という別解を挙げたり、例外の伝播における解決としてのJavaの検査例外に言及する等、まさになぜ例外処理がいまこうであるかを「歴史」を参照し、繙いていきます。

我々は、ふだん自分が慣れ親しんでいるものを最上と考えたり、また、そうでないにしても「あたりまえ」と考えてしまいがちです。前述の通り、プログラミング言語が問題に対する多用な解決策を提供するものであるからには、ただひとつの言語をもって唯一の解答とするのではなく、先人の積み上げてきた紆余曲折を学ぶことには大きな意義があるのではないでしょうか。

個人的に本書は、ちょうど『起源のインターネット』や『チューリングの大聖堂: コンピュータの創造とデジタル世界の到来』といった本を読んだ折、再び歴史に関心を向けていた時期だったのでタイムリーでした。そうでなくとも、広く様々な言語についての知識を、わかりやすい記述でもってプログラミング言語の各要素それぞれにおいて与えてくれる本書は、より知識を深めたい向学のプログラマにとって、必読の本であると思いました。

最後に、Perl Monger/Rubyistとして気になったことを2点。

Perlではオブジェクト指向を取り入れる際に、関数を束ねておくためのパッケージと、変数を束ねておくためのハッシュを結び付ける、という選択肢を取りました。

(本書p.190より)

この点、実際にはハッシュ(リファレンス)が、パッケージにblessされるデータ構造として採用されることは多いとはいえ、ハッシュに限るわけではありません(著者は重々承知だとは思いますが)。ただ、ハッシュ(リファレンス)をblessしたオブジェクトは、一般のOOP言語に見られるメンバ変数/メソッドの対と相似するため、このような説明になるのは文脈上、それほど不適当というわけではないでしょう。

Rubyにも2.0でモジュールをトレイト風に扱うためのmixメソッドが導入されます。

(本書p.234より)

Module#mixは結局取り入れられなかったようです。取り入れないという決定をした議論のログがあるかなと探してみたけど、見つかりませんでした。