ボトムアッププログラミング
1993年
(このエッセイは『On Lisp』の序文からの抜粋です。)
プログラムの機能要素はあまり大きくすべきではないというのは、プログラミングスタイルの長年の原則です。プログラムの一部が容易に理解できる段階を超えて大きくなると、それは大都市が逃亡者を隠すようにエラーを隠す複雑さの塊となります。そのようなソフトウェアは読みにくく、テストしにくく、デバッグしにくいものになります。
この原則に従って、大きなプログラムは部分に分割されなければなりません。そして、プログラムが大きければ大きいほど、より多く分割されなければなりません。プログラムをどのように分割するのでしょうか?伝統的なアプローチは「トップダウン設計」と呼ばれるものです:「プログラムの目的はこれら7つのことを行うことなので、7つの主要なサブルーチンに分割します。最初のサブルーチンはこれら4つのことを行わなければならないので、それ自体が4つのサブルーチンを持つことになります」というように進めます。このプロセスは、プログラム全体が適切な粒度レベルになるまで続けられます。各部分は、実質的な何かを行うのに十分な大きさですが、単一の単位として理解できるほど小さいものです。
経験豊富なLispプログラマーは、プログラムを異なる方法で分割します。トップダウン設計と同様に、彼らは「ボトムアップ設計」と呼べる原則に従います。問題に合わせて言語を変更するのです。Lispでは、プログラムを言語に向かって書き下ろすだけでなく、プログラムに向かって言語を構築します。プログラムを書いているときに「Lispにこんな演算子があったらいいのに」と思うかもしれません。そこで、あなたはそれを書きます。後で、新しい演算子を使うとプログラムの別の部分の設計が簡素化されることに気づき、といったことが続きます。言語とプログラムは一緒に進化します。二つの戦争状態の間の国境のように、言語とプログラムの境界は引かれ、再描画され、最終的には問題の自然な境界である山や川に沿って落ち着きます。最終的に、あなたのプログラムは、言語がそれのために設計されたかのように見えるでしょう。そして、言語とプログラムがうまく適合すると、明確で、小さく、効率的なコードが得られます。
ボトムアップ設計が単に同じプログラムを異なる順序で書くことではないことを強調する価値があります。ボトムアップで作業すると、通常は異なるプログラムが得られます。単一の巨大なプログラムの代わりに、より抽象的な演算子を持つより大きな言語と、それを使って書かれたより小さなプログラムが得られます。まぐさ石の代わりに、アーチが得られるのです。
典型的なコードでは、単なる簿記に過ぎない部分を抽象化すると、残りははるかに短くなります。言語を高く構築すればするほど、トップダウンでそれに到達するまでの距離は短くなります。これにはいくつかの利点があります:
-
言語により多くの仕事をさせることで、ボトムアップ設計はより小さく、より機敏なプログラムを生み出します。短いプログラムは多くのコンポーネントに分割する必要がなく、コンポーネントが少ないということは、読みやすくまたは変更しやすいプログラムを意味します。コンポーネントが少ないということは、コンポーネント間の接続も少ないということであり、したがってエラーの可能性も少なくなります。工業デザイナーが機械の可動部品の数を減らそうとするように、経験豊富なLispプログラマーはボトムアップ設計を使ってプログラムのサイズと複雑さを減らします。
-
ボトムアップ設計はコードの再利用を促進します。2つ以上のプログラムを書くとき、最初のプログラムのために書いた多くのユーティリティは、後のプログラムでも役立ちます。一度多くのユーティリティの基盤を獲得すると、新しいプログラムを書くのに必要な努力は、生のLispから始めなければならない場合のほんの一部で済むかもしれません。
-
ボトムアップ設計はプログラムを読みやすくします。この種の抽象化のインスタンスは、読者に汎用の演算子を理解するよう求めます。機能的な抽象化のインスタンスは、読者に特殊目的のサブルーチンを理解するよう求めます。[1]
-
コードの中のパターンを常に探すようにさせるので、ボトムアップで作業することは、プログラムの設計についてのアイデアを明確にするのに役立ちます。プログラムの2つの離れたコンポーネントが形において類似している場合、その類似性に気づき、プログラムをより簡単な方法で再設計するかもしれません。
ボトムアップ設計は、Lisp以外の言語である程度可能です。ライブラリ関数を見るときはいつでも、ボトムアップ設計が起こっています。しかし、Lispはこの部門でより広範な力を与え、言語を拡張することはLispスタイルにおいて比例して大きな役割を果たします。そのため、Lispは単なる異なる言語ではなく、プログラミングの全く異なる方法なのです。
この開発スタイルは、小さなグループで書けるプログラムにより適しているのは確かです。しかし、同時に、それは小さなグループでできることの限界を拡張します。『人月の神話』で、フレデリック・ブルックスは、プログラマーのグループの生産性はそのサイズに線形に成長しないと提案しました。グループのサイズが増加すると、個々のプログラマーの生産性は低下します。Lispプログラミングの経験は、この法則をより楽観的に言い換える方法を示唆しています:グループのサイズが減少すると、個々のプログラマーの生産性は上がります。小さなグループは、相対的に言って、単に小さいという理由で勝つのです。小さなグループがまたLispが可能にする技術を利用すると、それは完全に勝つことができます。
新着: 『On Lisp』を無料でダウンロード。
[1] 「しかし、あなたの新しいユーティリティをすべて理解しないと、誰もプログラムを読むことはできません。」なぜそのような主張が通常間違っているのかを理解するには、セクション4.8を参照してください。