今朝は、ビジュアルプログラミングとの関連で、”tex.web” というプログラムを斜め読みしています。
そこでひとつの発見をしたかもしれません。バグのないコードは短いです。少なくともKnuthのTeXは。TeXのプログラムは1,379個のモジュールから構成されていますが、そのうち8個の例外を除いてすべて1ページに収まっています。それも、コメントどころではない非常に詳しい解説つきで。
なにが言いたいのかというと、プログラムは一画面で見渡せる程度の規模のモジュールの組み合わせから作るべきだということです。で、それがどうしてビジュアルプログラミングに関係するかと思ったら、それは先を読んで下さい。
tex.web とは、数物系の論文執筆によく使われているLaTeXという組版システムの核にあたるTeXと呼ばれる部分のプログラムです。TeXはある種のプログラミング言語で、組版のための命令列を元に組版ずみの画像を生成します。TeX 自身は比較的小さなシステムなのですが、その言語機能を利用して大幅に拡張されたものが、今日、多くの人々が使っている LaTeX です。
で、どうしてこのTeXに興味を持ったかというと、これが恐ろしくバグが少ないシステムだからです。現在の TeX のバージョンは3.1415926です。詳しいことは調査中なのですが、バージョン番号の小数点以下の桁数は1990年代にTeX3.0が発表されてから見つかったバグの数のようです。つまり、20年近くのあいだに見つかったバグがわずか7個ということです。
ちなみに、TeX のバグを報告すると懸賞金がもらえることになっています。いまなら、$327.68だそうです。たしか、バグがひとつ見つかるごとにこの額は倍になっていたはず。
どうすれば、このようにバグが少ないプログラムが書けるのでしょう。興味あるでしょう?見たい人は以下をやってみて下さい。
– tex.web をググッてダウンロード
– touch change-file
– weave tex
– pdftex tex
こんな次第で、このプログラムの内容、特にどのように構成されているのかに興味を持ったのです。
パラパラと眺めていて、まず気づいたことは、各モジュールがページに収まっていることでした。プログラムだと長くなって、隣りのページにはみだしたりしそうなものですが、そういうことになっているモジュールはあまりなさそうでした。
モジュールの定義が1ページに収まっているということは、そのページでモジュールの内容が一覧できるということですし、ここからは想像になりますが、それを編集しているときのソースコードも一画面に収まっているのではないかと思います。((この点は要調査))
本当にそうか確認したかったので、この例外をすべて探したところ以下の例外が見つかりました。
– 208. 55個の定数定義
~ (p. 74, < 1.3 pages)
– 236. 59個の定数定義に続いて,それらに関連するマクロの定義(約65個)
~ (p. 91, < 2.4 page)
– 237. 巨大なディスパッチャ (case n of 56種類のパターン)
~ (p. 94, 1.2)
– 398. 59. で定義したシンボルをハッシュに追加するコード
~ (p. 96, < 1.2 page)
– 247. 22種類の長さの定義,それを扱うためのマクロ,そしてそれぞれを表示するための手続きの定義
~ (p. 99, 1.5 pages)
– 307. スキャナが使う16個の定数の定義.そのまえの説明が長い
~ (p. 125, 1.1 pages)
– 585. DVI ファイルに現れる全250種類のコマンドの説明.コードは書かれていない.
~ (p. 215, 3.5 pages)
– 768. Alignment の概念とTeXによるalignmentの処理の方法についての説明.コードは書かれていない.
~ (p. 285, 1.9 pages)
このように基本的には大規模な定数群の定義と複雑な内容を言葉で説明している個所だけが例外だということがわかりました。
ここまで引っ張っておかれたビジュアルプログラミングとの関係ですが、ビジュアルプログラミングを経験した方ならばわかると思いますが、画面の面積が貴重なのです。ひとつひとつのアイデアが画面のなかで面積を占めます。視覚的な配置によってアイデアの関連性が文字で書かれたものよりもわかりやすく配置されたならば、ビジュアルプログラミングは有用ということになるはずです。これ自体が狭い応用領域を除くとあまり成功していないのですが、それとは別の問題があります。
たとえば、以下が最近、私が作って授業のなかで紹介したコッホ曲線を描くScratchのプログラムです。まずは、プログラムの出力です。正三角形の辺を三等分した中央に小さな正三角形をくっつける操作を再帰的に行っています。
そして以下がプログラムです。
このプログラムは主に二つのモジュールから構成されています。中央に描かれているのが描画処理です。''命令列'' というリストに「直進、左、右、左」のような命令列が格納されているので、それにしたがって逐次的に描画しています。それぞれの命令がなにをするのかは、中央の下の「*を受け取ったとき」の処理に書かれています。
右側のモジュールは、再帰がないScratchに再帰的な処理をさせるための工夫です。ここでは''n''次のコッホ曲線に対応した命令列が与えられたときに、それを''n+1''次の曲線に変換する処理を行っています。簡単に言えば、''n''次の曲線のなかの各命令について、「命令、直進、左、右、左」に置き換えているだけです。
このプログラムを見ていて不安になるのは、このような簡単なプログラムだったらいいけれども、一般のシステムの場合には、複雑な論理を備えているので、画面から溢れてしまうのではないかということです。ぼくも不安になってきて、そもそも「ソフトウェアのモジュールをコンパクトに記述するのは可能なのか」という疑問を抱いたのです。そこで思いついたのが TeX でした。TeX はプログラムの規模はさほど大きくありませんが、メモリ管理、制約を用いた行やページの分割、表組み、図や表の配置、英単語に対するハイフネーション処理など興味深い機能がさまざま実装されています。使用しているアルゴリズムも、当時知られているもので最高峰のものが採用されていると聞きます。
つまり、コードは1ページに収めることができるということを、あの複雑な処理を行っているTeX で観察できた点は重要と思われます。
TeX だけでなく、多くのプログラムについて調査すべきだと思うのですね。これまた恐ろしくバグが少ないことで知られている qmail かな?というか、こういうことはソフトウェア工学で疾うの昔に議論されているはずですね。
ところで、TeXもqmailも数学者が作ったシステムです。優秀なプログラマにとって数学のトレーニングが重要なことの証左になるでしょうか。