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