2006年06月25日

本物

 Windows専用の言語処理系のひとつに、HSPというものがある。

 HSPの機能のいくつかは、月の裏側から集めてきたらしい。不要とわかって捨てられたものを、わざわざ復活させている。たとえばC言語風のマクロだ。私見では、#defineと#ifdefは手動メモリ管理に次ぐ害悪だ。Stroustrup『C++の設計と進化』540ページより引用する:

マクロの定義は、環境の中や、コンパイラのディレクティブ、ヘッダファイルなど、いろんなところに潜んでいる。マクロによる置換はスコープという境界ルールを無視し、それどころか、勝手にブレースや引用符を挿入してプログラムのスコープ構造を変えてしまうこともある。(中略)その機能はあまりにも構造性を欠き侵略的なので、プログラマやメンテナ、コードを移植する人、ツールの作者などにとってつねに頭痛の種だった。

 しかしHSPは当たった。同種のWindows専用の言語処理系のなかで、一番の大当たりになった。
 なぜ当たったのか? 私はこういう世界とはまったく縁がないので、説得力のある意見をとりあえず信じることにする。私の知るかぎり、もっとも説得力のある説明は、以下のとおりだ。
 「インストーラ抜きの配布物がEXEファイル1個になる。それが本物っぽくて、いい」
 VBの配布物はEXEファイル1個にはできない。ランタイムが必要だ。Perlは、PARを使えばEXEファイル1個にすることはできるが、PARを使うにはかなりの知識が要る。その点、最初の最初から「本物っぽい」配布物が得られるHSPは、人をひきつけたのだ――配布物がEXEファイル1個になるのが「本物っぽい」と感じるような初心者を。
 初心者がなにを「本物っぽい」と感じるかは、なかなかわからない。彼らはカーゴ・カルトの世界にいる。

 初心者でなくなるのは簡単だ。慣れればいい。だが慣れるだけではカーゴ・カルトからは抜け出せない。信仰しているカーゴ・カルトが、「ベスト・プラクティス」という名前になるだけだ。
 『本物のプログラマはPascalを使わない』というあのエッセイは、そこの機微をよく捉えている。このエッセイによれば、本物のプログラマはFORTRANを使うのだという――FORTRANは当時のカーゴ・カルトだったのだろう。EXEファイル1個の配布物が「本物」であることと、FORTRANが「本物」であることのあいだには、大した違いはない。
 さて、今日の本題に入ろう。ネイティブ・コンパイラ(ネイティブに実行可能なバイナリ・ファイルを生成するコンパイラ)を信仰するカーゴ・カルトについて。

 基本を確認しよう。
 C言語のコンパイラはC言語で書ける。C言語で書かれたCコンパイラは、自分自身をコンパイルできる。
 問題は、最初の実行だ。世界で初めてC言語の処理系を書いたのなら、ご愁傷様だ――手作業でなんとかするしかない。だが、ほかにC言語の処理系がすでに存在していて使えるなら、手作業は必要ない。
 さて応用である。
 JITコンパイル型のJava VMは、自分自身を実行できる。
 事の本質はCコンパイラとなにも変わらない。「最初の実行」という問題が、VMを起動するたびに起こるだけだ。なんらかの方法で起動しさえすれば、あとはVMが自分自身を実行する。起動方法としては、インタプリタ型のJava VM(速度は非常に遅くていい)などが考えられる。そしてその起動用VMも、FORTHインタプリタのような極小のVM上で動かすことができる。最小限のFORTHインタプリタは非常に簡単に書けるので、アセンブラさえいらないくらいだ。
 高度な動的最適化は、理論上も現実にも、コンパイル時最適化をしのぐ。ある程度以上のメモリのある環境なら、ネイティブに実行可能なバイナリは、BIOSとブートローダとカーネルのごく一部にしか必要でない。ネイティブ・コンパイラはほとんど不要だ。
 (ただし、ネイティブでないコンパイラは相変わらず必要だ。コンパイル時の型チェックはプログラマを助け、冗長性の低いバイトコードは実行効率を高める)

 EXEファイル1個の配布物。FORTRAN。ネイティブ・コンパイラ。
 どれも、ある条件のもとでは、ベストな選択だ。だが、その条件を判断する知識が抜け落ちたとき、その選択はカーゴ・カルトになる。
 このようなカーゴ・カルトを見分けるキーワードが、「本物」だ。
 なにかを選ぶとき、それが「本物」だからという理由で選んではいないか。なにかが確かだと思うとき、その根拠がどこかで「本物」につながってはいないか。
 選ばれて「本物」になる。確かだと思われて「本物」になる。だが、その逆は、カーゴ・カルトだ。

Posted by hajime at 2006年06月25日 23:46
Comments

>JITコンパイル型のJava VMは、自分自身を実行できる。

これ、何かおかしいと思うのですが。
「Java で書かれ(てバイトコードになっ)た Java VM は~」
の間違いではないでしょうか?

Posted by: 匿名希望 at 2006年07月01日 14:18

 Java VMが解釈するのはJavaの
バイトコードなので、自分自身を実行する
Java VMは当然Javaのバイトコードで
書かれています。

Posted by: hajime at 2006年07月01日 16:02

「JIT コンパイル型の Java VM は、全て、自分自身を実行できる」
と読んでしまったので、間違いだと思ってしまったようです。

Posted by: 匿名希望 at 2006年07月01日 23:18