ドナルド・クヌース「文芸的プログラミング」(1984年)を読む

世界最高のプログラマーは誰か?

計算機の祖であるアラン・チューリングだろうか? あるいはUNIXシステムの開発者デニス・リッチーだろうか?

ひとりだけ挙げるとすれば、個人的にはドナルド・クヌースを推したい。

ドナルド・クヌースが1984年に書いた論文「文芸的プログラミング」(Donald Knuth, Literate Programming, California, 1984)を読み直す。

ドナルド・クヌースとは?

ドナルド・クヌース(Donald Ervin Knuth、1938年-)は米国の計算機科学者だ。アルゴリズム解析やプログラミング言語の設計で知られており、コンピュータサイエンスの発展に大きく寄与した。

具体的な業績として、自動組版システム「TeX」(テフ)の開発がある。おそらく理数系の出身であれば、レポートや論文でTeXに慣れ親しんだ人も多いだろう。誕生から40年以上が経過した現在でも、TeXのコミュニティでは精力的に開発が進められている。

あるいはまた、アルゴリズム解析に「漸近記法」を取り入れ始めたのもクヌースだ。漸近記法はオーダー記法やランダウの記号とも呼ばれ、アルゴリズムの大まかな計算量を求めるのに用いられる。競技プログラミングで馴染み深いO(nlogn)といった表記は、この漸近記法の一種である。

アルゴリズム解析の歴史をまとめた『The Art of Computer Programming』は、クヌースのライフラークといえる大著。第4巻の途中で刊行が止まっているが、クヌースのホームページでは今後の執筆計画も発表されている。

こうした数々の功績が認められ、クヌースは1974年にチューリング賞を受賞。スタンフォード大学教授などを務め上げている。

「文芸的プログラミング」(1984年)

構造化プログラミングに対する問いかけ

1984年に発表された論文の中で、クヌースは「文芸的プログラミング」と呼ばれる概念を提唱した。

端的にいえば、文芸的プログラミングとは「文章を書くようにコードを書く」ための手法である。

「文芸的」(literate)という言葉には、当時さかんに叫ばれていた構造化(structured)プログラミングに対する警鐘の意図が込められている。

構造化プログラミングとは、プログラムを平易にするため、全体のフローを個々に分割することを指す。主に「順接」「反復」「分岐」という3種類の制御構造を組み合わせ、書きやすく読みやすいプログラムを実現する考え方だ。

歴史的に見ると、構造化プログラミングはエドガー・ダイクストラに端を発するgoto文論争によって広まった。

アセンブラや初期の高級言語で使われていたgoto文は、コードの可読性を損ない、全体の見通しを悪くする。そこでダイクストラは、デバッグを容易にし、メンテナンス性を高めるためにgoto文の廃止を訴えたのである。

構造化プログラミングの手法は、今でこそ自明のものとなっている。ほとんどの言語においてgotoの使用は推奨されず、代わりにコードブロックやクロージャによって制御機構を強化している次第だ。

ところが、当時のクヌースはまったく異なるアプローチを考えていた。

1970年代には、他の人たちと同様に、私も構造的プログラミングのアイデアに同調した。なぜなら構造的でないプログラムを書いて、咎めだてを受けたくなかったからである。しかし今、とりかえす機会がきた。「文芸的プログラミング」という言葉を発明することによって、このことばを聞いた人たちにモラルを寄与している。読めないような(literateでない)プログラムを書いていることを誰も認めたくないことは確かだからである。

『文芸的プログラミング』アスキー出版局、136頁。

もともとクヌースは、プログラミングをアートの一種と捉えていた節があった。ここでいうアートとは、一般的な意味の「芸術」というよりも、熟練した技術によって生み出される作品、いわば「技芸」の類と考えてもらって構わない。

60年代末にコンピュータ・サイエンスの分野が確立され、自身もその第一人者として発展に寄与するかたわら、クヌースはプログラミングに純粋な美学を見出していた。

だからこそ、彼は構造化プログラミングに対して警鐘を鳴らしたのだろう。それだけにとどまらず、クヌースは文芸的プログラミングを実践する環境として、まったく新しい言語「WEB」の開発に乗り出した。

実験的なWEB言語の体系

こんにちWEBと聞けば、誰もがインターネットのそれ(World Wide Web)を思い浮かべる。だが、クヌースによる「WEB」の開発はインターネットの誕生よりはるか昔、1970年代のことだった。

WEBは文芸的プログラミングを実現するための言語仕様だ。具体的には、自身の開発したTeXをPASCALと組み合わせ、ドキュメントのような形式でプログラムを記述する。

WEBはソースコードをマクロで置換する仕組みであり、非常に移植性が高い。そのため、後にPASCALをC言語に置き換えた「CWEB」が開発されている。

たとえば、以下はCWEBの一例として挙げられた、UNIXのwcコマンド(テキスト中の単語数を数えるコマンド)を実装するプログラム(抜粋)である。

The present section, which does the counting that is wc's raison d'être, 
was actually one of the simplest to write. We look at each character and 
change state if it begins or ends a word.
[このセクションはwcの存在理由である計数を行う部分であるが、実は書くのが最も簡単な部分
のひとつである。個々の文字を見て、それが語の先頭か末尾であれば状態を変える。]

<Scan file 15>
 while (1) {
  <Fill buffer if it is empty; break at end of file 16>;
 c = *ptr++;
 if ( c  > ' ' ∧ c < '177) { { visivle ASCII codes }
  if (¬in_word) {
	 word_count++;
	 in_word = 1;
  }
  continue;
 } if ( c ≡ '\n') line_count++;
 else if ( c ≠ ' ' ∧ c ≠ '\t') continue;
 in_word = 0; {c is newline, space, or tab}
}
『文芸的プログラミング』アスキー出版局、432頁。

説明文とソースコードが混在している。このように、TeXによる文章とC言語によるソースコードを包括的に扱う仕組みがCWEBだ。

一般的なプログラミング言語との違いは、通常の言語がソースコード⇒コメントの順に書かれるのに対して、WEB言語が説明文とソースコードが並行して記述される点にある。

テキストはマクロが織り込まれており、weaveというプログラムに通すとTeXを用いたドキュメントが、tangleというプログラムに通すとC言語のソースコードが生成される。

時代を超えるクヌースの問い

今となってみれば、クヌースが掲げた「文芸的プログラミング」が一般に普及することはなかった。

説明文とマクロを組み合わせたWEB言語のスタイルは、たしかにプログラムの意図を明確にする。デバッグの時間短縮につながることは間違いなく、何よりウィットに富んでいる(先の引用にあるraison d'êtreという表現からは、クヌース流のジョークが垣間見える)。

一方で、但し書きを含んだソースコードは冗長になり、開発コストを膨らませる。現在のコーディング環境において、およそ実用的であるとは思えない。

だが、それでも「文芸的プログラミング」は私たちに自明の事実を提示してくれる――プログラムは機械に理解させるものであると同時に、人間に理解させるためのものでもあるのだ。

コーディング・スタイルをめぐる議論はいまも絶えないが、クヌースの教えは極めてアクチュアルなものとして、私たちの前に残されている。

42 Tokyoでエンジニアへの一歩を踏み出す

(引用:42 Tokyo公式HP

東京・六本木に拠点を置くエンジニア養成機関「42 Tokyo」では、学生同士のピア・ラーニングを基本理念として、質の高い教育環境を無償で提供している。

性別や年齢、経歴は問わない。たとえプログラミングが未経験でも、これから好きになる意志さえあれば入学できる。

あなたが/あなたの世界を塗り替えたいと思ったら、今すぐ4週間の入学試験「Piscine」に飛び込もう。

おすすめの記事