ソフトウェア設計論
(6)

【プログラミング】美しさ


── 美しいプログラムを作るには

 プログラムは美しくなければならない。ソフトウェア技術者の作るプログラムは、単に「正しく動作すればよい」というものではなく、第三者がそのプログラムを読んだとき内容を容易に理解でき、作成者の意図が読み取れるものでなければならない。更に欲を言えば、作者のコーディング哲学とか設計理念などが行間から読み取れて、プログラムの目的以外の何ものかを読む人に伝えられるものであることが理想である。そのためには、プログラムは一定の基準に則って整然と記述されたものでなければならず、共感を持って読めるような美しいものであることが要求される。

 新人のソフトウェア技術者が最初にやる勉強は、先輩の作ったプログラムをトレースして解読することである。そのとき「ドキュメントがないので分からない」というボヤキをよく耳にする。ソフトウェア技術者はソフトウェア開発の各段階で資料として何を残さなければならないか、もはや常識として徹底されているはずなのに何故いまだにこのような話が出てくるのだろうか。プログラムはあるけれど、情報伝達の役には立たないような代物のプログラムばかりを作っているからではなかろうか。読んで内容の理解できる「美しいプログラム」を作ることを、我々は忘れてしまっているのではないかと思うのである。

 コンピュータ開発の黎明期では、技巧的で名人芸のプログラムをいかにして作るかが主たる関心事であった。代表的なプログラムとしてイニシャルオーダーがある。電源投入直後のコンピュータメモリに最初にプログラムを読み込ませるためのもので、技巧的で名人技を必要とするプログラムとしては代表的なものである。これには(何等かの手段で)最初に読み込んだ数語のデータを巧妙に命令として利用し、自己増殖させていってプログラムテープ上のデータを読み込むものでインタールードというテクニックが使われていた。美しさよりも、いかに簡潔で短いプログラムを巧妙に作るかが最も重要な課題だったのである。しかし高水準の記述言語の時代を迎え、プログラムは読みやすさや理解しやすさを重視する時代になった。

 以前、私はMITの近くにある研究所でMulticsを利用して仕事をしていた時代があった。その研究所にフライバーグハウスという男がいて、実に美しいプログラムを書いていたのを思い出す。彼は、標準PL/Iの言語仕様をきめたことで知られる男であるが、彼の書くプログラムは(大袈裟にいう積もりはないが)本当に溜め息が出る程美しいものであった。使用していた記述言語はPL/Iのサブセットで、小文字を用いて記述されていた。丁度今のC言語のようなシンプルな言語仕様のものであった。幅の広いラインプリンタ用紙一杯に、彼の見事に構造化された記述が展開されているプログラムを見せられると、そのプログラムリストが芸術品のように私には思えたものである。成る程プログラムとはこのように書くものなのか、と私は深く深く感じ入ったものであった。それまでカードベースで(80欄のうち72欄しか使えない)狭い範囲の中でプログラムを書いてきた者にとっては、TSS端末(CRT端末ではなくまだテレタイプ型だった。この翌年くらいから出力先にCRT画面が使われるようになった)からのプログラム入力は、欄の幅にとらわれない自由なコーディングができるので、まさにプログラム作りで自由な広い土俵が与えられたという思いがしたものである。以来、ひたすら彼のコーディングテクニックを盗むことに徹し、実に多くのことを学ばせてもらった。

 彼のプログラムは、無駄な注釈がなく変数をうまく命名して文を記述するので、丁度英語の文章を読むようにプログラムを読むことができた。流れ図などをまったく必要とせず、プログラムそのものがドキュメントとなっていた。初期値設定などで同じような記述ステップが散在している場合、我々の感覚だと goto 文で合流させて1箇所にまとめて記述するように変更したくなるところであるが、彼はそのようなセコイことは決してしなかった。実に自然の発想のままに記述するのである。私は試しに彼のプログラムを goto 文を使って書き直してみたが、プログラムの長さは確かに短くはなったものの、スパゲッティのように絡み合った見にくい(醜い)プログラムになってしまった。成る程、と私は自分で納得してその書き換えたばかりのプログラムリストを屑籠に投げ捨てたのを覚えている。後年、日本でも“構造化プログラミング”とか“goto-less プログラミング”とかいわれだした時、秀れたプログラマは昔から実践していることばかりだと思ったものである。偉い学者は、それを理論としてまとめ上げる点が我々凡人とは違うのであろう。

 小文字で書いたプログラムの美しさを知ったのもこの頃である。以来プログラムは小文字で書くものと決めている。後にC言語で普及したカーニハン&リッチー流のコーディングスタイルは、フライバーグハウス流のプログラミングスタイルと比較すると、お世辞にも美しいとはいえない。
 プログラマは、自分の“プログラミングスタイル”を持つべきである。プログラムを書くことは普通の文章を記述するのと同じであるから、独特の文体になるのは当然である。自分で納得のいくスタイルを模索し、自からのスタイルを確立していくとよい。それができない人は、他人のプログラムを見て気に入ったスタイルがあればそれを真似るとよい。他人のスタイルを真似たからといって訴えられる心配はない。ただし、プログラムというものは他人に読んでもらうことを前提にする以上、他人に受け入れてもらえるスタイルでなければならない。また、慣習として広く使われてきた表記法はできるだけ変えない方がよい。

参考までに、美しいプログラムを書くためのポイントをいくつか列挙してみよう。

(1)空白の扱いを大切に
 プログラムの構造を明確にするために桁ずらし(インデンテーション)を利用するのは当然のことであるが、桁をずらすには空白コードを連ねるのではなくタブコードを利用するとよい(タブセットの位置は、たとえば、8, 16, 32 … のようにあらかじめ決めておく)。そしてタブ位置からの微調整に空白コードを利用する。1つの空白の挿入位置にもこだわって、文の配置に細かく気を配る努力が必要である。

(2)注釈について
 注釈の多いプログラムは、必ずしも美しいとは言えない。一般の書物でも脚注や注釈の多い本は読みにくいものである。アセンブラ言語でプログラムを書く場合には、注釈は必須である。命令とオペランドだけを書いて右側の注釈欄をすべて空白にしておいたりするとプログラマとしての能力を疑われたりする。高水準言語での記述でも、普通には注釈をたくさん書くことが推奨されている。市販のプログラミング言語の入門書を見ても豊富な注釈付きのプログラムが載っている。しかし、これはよそ行き用に着飾ったプログラムであって、普段のプログラム作りでこれを実践するのは手間が掛かって難しい。美しいプログラムには余計な注釈は不要である。
 注釈がどうしても必要な場合には、プログラムの先頭にまとめて全体の説明を入れるようにするとよい。あるいは、プログラムの区切り目(段落)に1行注釈の形で簡潔に挿入する。1行中の文と文の間には注釈を書くべきではない。文と行末の間も(データ宣言部への注釈以外は)できるだけ避けた方がよい。プログラムの美しさが損なわれるからである。ただし、どうしても注釈が必要な場所なら書くのを躊躇すべきではない。行末に注釈を書きたければ“値千金の注釈”に限るべきである。

(3)表意変数の活用
 それでは、注釈なしで分かりやすいプログラムを記述するにはどうしたらよいか。それには変数の命名法を工夫すればよい。単に、

   a, b, c
   test1, test2

というような想像力に欠けた無機的な名前付けをするのではなく、使用目的がはっきりと分かるような表意変数を用いる。たとえば、次のように書くと注釈は不要であろう。

 const isNumeric = isReal || isInteger;

   if ( CurrentToken -> Attribute & isNumeric )
      ReadNumber( &data );
   else
      ReadString( &data );

 逆に、ループのインデックス変数などには i, j, k といった無機的な名前付けを用いるとよい。変数の名前のつづりをいくら長く(あるいは短く)しても、普通は(インタプリタ形式でない限り)プログラムの実行時間には影響しないものである。

(4)抽象化の活用
 プログラムの複雑さに対抗する最も良い方法は、抽象化の手法を活用することである。たとえば、数学の世界では複雑な概念を抽象して簡単な記号で表現する。そして、その記号を(本来の意味から離れて)機械的な操作対象として扱い、より高度で複雑な議論の展開へと意識を集中できるようにする。
 これと同じようにプログラムの世界でも「手続き抽象」や「データ抽象」の手段によって、手続きの実装方法やデータ構造の細部にかかわらずにそれらを扱うことができるようにするとよい。プログラムを美しく表現するポイントは、何をどのように抽象化するかに掛かっている。
 利用者定義の新しい型を導入したり、一連の操作を一つの手続きにしてしまって演算子のように扱うとよい。その際重要なことは、できるだけ実生活で出くわす事象をモデルにして、型や手続きを命名することである。想像力を逞しくして擬人的な表現を採用するとよい。これによって簡潔な記述で内容の深い、密度の濃い表現が可能となる。

 ところで、プログラムが美しいかどうかの評価・判断は、多分に個人の好みにかかわる領域の問題である。したがって、プログラミングスタイルの表現を凝り過ぎて、第三者に受け入れられない独り善がりのものにならないよう注意しなければいけない。我々は常に仲間とチームを組んで仕事をしている訳である。今は仲間がいなくても、何時か自分の書いたプログラムを解読して利用しようとする人が出てくるかもしれない。それは貴方(貴女)の大切な後輩であるかもしれない。我々は常にそのことを念頭に置いて、日々のプログラム作りに励むべきであろう。■