2015-12-20

"プログラミング作法" Brian Kernighan & Rob Pike 著

次のような経験をしたことはないだろうか... と、いきなり問いかけてくる。見透かされたかのように。どうせ、おいらはすべて経験済みさ!
  • 間違ったアルゴリズムでコーディングしてやたらと時間を無駄にした
  • 使用するデータ構造が死ぬほど複雑になった
  • プログラムをテストしたのに明白な問題点を見落としていた
  • 5分もあれば見つかるはずのバグを1日がかりで探し回った
  • プログラムを3倍速くしメモリ使用量も減らしたいと思った
  • ワークステーションとPCの間でプログラムを移植するのに苦労した
  • 他人のプログラムに少々変更を加えようとした
  • さっぱり理解できないプログラムを書き直した

問題解決のための手段の一つに言語があるが、その選択は目的次第。おそらく、すべての問題を同時に、効率よく、解決できる言語は存在しないだろう。なんでもやれることを望めば、低水準へ向かうことになる。だがそれでは、ソフトウェアの本質である簡潔性、効率性、移植性が維持できるはずもない。相対的な価値観しか持ち得ない知的生命体が、万能な言語を編み出すことなど不可能であろうから。それでもなお、ソフトウェア工学に普遍観念なるものを求めるとすれば...
「どんな言語で書くにせよ、プログラマとしての読者の任務は手もとのツールを使ってベストを尽くすことだ。良きプログラマは貧弱な言語や使いづらいオペレーティングシステムを克服できるが、悪しきプログラマを救うのはたとえ最高のプログラミング環境だろうと不可能だ。読者の現在の経験や実力がどの程度であれ、本書を参考にして実力を向上させ、プログラミングの楽しみをもっと感じられるようになれば幸いだ。」

本書で紹介されるコード事例は、C言語族が中心で、やや古臭さを感じないではない。現在では、メモリ容量やプロセッサ性能など豊富なリソースを前提にした慣習が根付いている。しかし、哲学的な作法はあまり変わらない。ガベージコレクションのような自動化機構の性能がいくら高まっても、完全に頼るわけにはいかないだろう。ここには、数々の教訓が鏤められる。とりあえず、気に入ったものを三つ挙げておこう...
「悪いコードにコメントをつけるな、書き直せ!」
「最適化の第一の原則は最適化するな!」
「簡潔性と明瞭性は何よりも重要だ。これ以外のものはすべてここから派生すると言っても過言ではない。」

これは、C言語や UNIX の開発で知られるブライアン・カーニハンとロブ・パイクのベル研コンビが綴ったプログラミングの王道を問う物語である。

「人が歴史から学ぶことができたなら、歴史は我々にいかなる教訓を与えてくれるだろうか。だが、我々の目は感情と利害に覆われ、経験のもたらす光明も船尾にともるカンデラにすぎず、我々の背後に遠ざかる波を照らすだけなのだ。」
... Samuel Taylor Coleridge 「Recollections」

さて、本書の内容を大まかに拾うと...
  • 良きプログラミングには、良きスタイルが不可欠。美しく書けば間違いも少なくなり、デバッグや修正も楽になり、最初からスタイルを意識することになる。
  • 単純なアルゴリズムと単純なデータ構造を選択せよ。
  • 簡潔性と関連することの多い概念に一般性があり、その次に進化がある。
  • インターフェイスは、プログラミングにおける戦いのかなりの部分を占める。その最も当たり前のケースはライブラリだ。
  • 自動化は過小評価されている概念である。テストを系統的に整理し、自動化せよ。テストやデバッグだけでなく、コードの自動生成も含めて検討する価値がある。
  • 記法も過小評価されている。記法は、単にプログラマがコンピュータに作業を指示する方法ではなく、様々な種類のツールを実装するための有機的な枠組をもたらし、プログラムを記述するプログラムの構造を導き出す。
しかしながら、内容よりも数々の名文句に目を奪われる。こちらは、ちと細かく拾ってみよう...

1. スタイルとデータ構造について
スタイルとは、プログラミング哲学を意味し、これが本書の骨格を成している。アルゴリズムの美しさやデータ構造の単純さは、設計哲学の投影というわけか。

「昔から言われるように、最高の書き手は時にレトリックのルールを無視することがある。ただしそうした場合には、ルール違反を補ってあまりあるメリットがその文を通して読者に伝わるのが通例だ。それに確信が持てない限り、おそらく書き手はできる限りルールに従おうとするだろう。」
... William Strunk & E. B. White 「The Elements of Style」

「結局のところ、具体的な問題に適正に対処する方策はこの分野のツールとテクニックに馴染むこと以外に存在しないだろうし、クオリティの高い成果が一貫して得られるようになるには一定の経験を積む以外に手はないだろう。」
... Raymond Fielding 「The Technique of Special Effects Cinematography」

「私にフローチャートを見せてテーブルを隠しておいたなら、私はずっと誤魔化され続けるだろう。しかしテーブルを見せてくれればたいていはフローチャートなどいらない。一目瞭然だからだ。」
... Frederick P.Brooks,Jr 「The Mythical Man Month」

2. インターフェイスと実装について
「壁を築く前に私はよく自問した。何を壁の内に閉じ込め何を外に閉め出そうとしているのか、自分が誰を傷つけようとしているのか、と。どこかに壁を愛さないものがいる。壁を倒したがっているものが。」
... Robert Frost 「Mending Wall」

「設計の真髄は、競合する目標や制約をバランスさせることにある。小規模な自立したシステムを書いているときにもトレードオフを迫られることは何度もあるだろうが、個々の選択によって生じる影響はそのシステムの中にとどまるし、そのプログラマにしか及ばない。しかし他人に使われるコードの場合には、自分の判断がもっと広範な影響を及ぼす。」

「ライブラリやインターフェイスを一発で正しく設計できる可能性は低い。Fred Brooks がかつて言ったように、"捨てるつもりでいること。どうせ捨てることになるのだから"。Brooks が言ったのは大規模なシステムについてだが、この考え方は実用的なソフトウェアすべてに通用する。実際にプログラムを作成して使ってみるまでは、正しく設計するのに必要な課題を十分に認識できないのが普通だ。」

3. テストとデバッグについて
テストとデバッグはまとめて扱われることが多いが、両者をごっちゃにしてはならないという。大まかに言えば、デバッグは問題があると分かっている時の作業で、テストは正常に動作していると思われるプログラムを破綻させようとする確信犯的でシステマチックな作業... といったところか。

「テストによってバグの存在は証明できるが、バグの不在は証明できないという Edsger Dijkstra の有名な言葉がある。」

自分のコードを他人に説明することも、第三者の目を要請する効果的な方法となろう。コードレビューにしても、共通な書き方を求めるよりも、哲学の共有の方がはるかに重要である。そのために、しばしば雑談会となるが、仕事が楽しめればそれでいい。
例えば、技術問題で悩んでいるメンバーに、ちょっと説明してみてよ!と持ちかけると... ホワイトボードの前で自信なさそうに喋っているうちに、いつの間にか問題の根幹に気づき、解決法を自信満々に語り始める... といったこともよくある。
バグは確実に再現できる時は、恐れるに足らん!問題は再現できない時で、頻度が少なくても、深刻な問題を抱えていることが多い。

「打つ前に読め!効果的なわりに過小評価されているデバッグテクニックのひとつに、"コードを舐めるように読んで、変更を施さずにしばらくよく考えてみること" がある。... 早くキーボードを触りたいという気持ちを抑えること。思考はそれに勝るとも劣らない行為だ。」

「コードを最初から上手に書けばその分バグも少なくなるし、徹底したテストを実行していることに確信が持てるようになる。コーディング時に境界条件のテストを記述することは、くだらないちょっとしたバグを大幅に減らす手段として効果的だ。系統的なテストは潜在的な問題発生箇所を順序正しく調査する方法だが、この場合もやはり境界部分で間違いが見つかることがもっとも多く、手やプログラムでそれを検証できる。
テストはできるだけ自動化することが望ましい。回帰テストはプログラムが以前と同じ答えを出すことをチェックする。小さな変更を施すたびにテストを実行するやり方は、問題の発生源を絞り込むのに有効なテクニックとなる。新しいバグは、新しいコードで発生することが多いからだ。」

4. 慣習と標準化について
「最後に、慣習と同様に標準化も強制に近い形で立ち現れることがある。しかし慣習と違って標準化は近代建築においては現在のテクノロジーの凝縮された結果として是認されてきたが、一方でその潜在的な支配力と非人間性が懸念されている。」
... Robert Venturi 「Complexity and Contradiction in Architecture」

「おそらく人間によるあらゆる創造物の中でもっとも驚くべきものは言語である。」
... Giles Lytton Strachey 「Words and Poetry」

0 コメント:

コメントを投稿