§1.メタ記述




C++のプリプロセッサは貧弱である。簡単な文字置換にすぎない。
ある程度文構造を解析して何らかのプリプロセス作業をしてくれるならば、template以上のことが出来るだろう。私はそう思う。

一般にコンパイルというのは、与えられたコードをマシンコードに変換する作業である。マシンコードに直接変換せずに、アセンブリ言語や仮想マシン用のバイトコードや、CLIのような中間言語(CLIとはECMAの承認した共通言語基盤(CLI:Common Language Infrastructure))に変換することもある。

言ってみれば、文字列から、別の文字列に変換する。これのおかげで人間様は、抽象化されたコードで記述でき、泥臭いコードとおさらばすることが出来るわけである。(ある程度はね)

こうすることで、著しく生産性は向上する。アバウトな話だが、もし、C++の2倍の抽象度を持つ言語があって1/2倍の開発期間で済むならば、倍の仕事が出来るようになる。プログラムで1ヶ月50万儲けているのならば100万儲かるようになる。まあ、なかなか現実とはそんなに思い通りにいかないものだが、この生産性を向上させる抽象化について考えてみる余地はある。

抽象化というからには基準がなければならない。私は、少ないステップ数(行数)で記述できるのならば、それは抽象化だと思う。ただし、Perlみたく@や#で暗号化じみた記号を導入して可読性を下げて「プログラム短くなりました!」というのは何か違う気がする。

そこで、C/C++かRubyレベルの構文で、人様が読める範囲で、ステップ数が短くなるとき、これを抽象化と呼ぶことにする。

ただし、ライブラリに左右されることもある。一番肝心なのはコレクションクラスだろう。頻繁に使用すると思われるvector,list,map,set,hash,etc..。これらを利用すれば短くなるのは当然である。あとC++ではsort以外使いものにならないんじゃないかと思うalgorithm。あれも、まともな言語ならば使えるシロモノだろう。

しかし、ここでいまから論じるのは、そういう部分を省いた部分。純然たる構文レベルの話にとどめる。(そうしないと、収拾困難になる)

たとえば、C++で5回繰り返すためには次のように書くかも知れない。

list-1
for(int i=0;i<5;++i) {
        //  なにか
}


もう、この時点で、私は違うと思うわけだ。根本的にダメなのだ。ループと無関係のiという一時変数を導入している。(このiのスコープがVC++6/.NETではforの外まで伸びているのはこの際、目をつぶる)

同様の理由でvectorやlistに対してiteratorを用いて巡回するプログラムとかも、論外である。

じゃあ、C#のfor_eachに相当する構文や、Rubyのloopに相当する構文があれば良いのかということになる。そうではない。そういう構文はあれば当然便利だろうが、そういう構文が欲しいという欲求は際限なく出てくるものなのだ。そうでなければC++は最初からfor_eachを搭載しただろう。当時は、その重要性に気づかなかったのだ。C++になってからコレクションクラス(STL)を標準として取り入れたのも時代のニーズかも知れない。言語設計当初に、そういう部分はあまり見えてこないし、そのへんを見越して構文を(いろんな言語から取り入れて)いい子ぶった言語を作ったところで何かが新しいわけでもなければ、それで十分というわけでもない。

大切なのは、for_eachやloopと言った構文そのものをユーザーが定義するだけの言語的機能が備わっているかだ。冒頭でも述べたC++のプリプロセッサがもっと高機能ならば..というのは、そのことだ。

仮にそういう言語的機能が備わっているのならば、そのプリプロセッサを用いてC++のコードを生成しても構わない。つまり、コンパイルするとC++のコードが生成されという風にC++のプリプロセッサの代用として用いても全然構わない。

私が考えているのは、マクロだなんて生易しいものではない。あらゆる言語のプリプロセスとして用いることが出来る強力なメタコンパイラである。このようにすることで、将来的に開発言語が変わったとしてもこのメタコンパイラの仕組みを生かすことが出来る。Javaに、テンプレートを持ち込むことだって出来るだろうし、C++にJava的なinner classやfor_eachを導入することもたやすい。可能性は無限である。