このソフトウエアの生産性にもっとも影響するのが プログラミング言語であり、 コンピュータが誕生した直後から 計算機科学における重要な研究分野となっている。 最初のプログラミング言語 FORTRAN に始まり、 構造化プログラミング、オブジェクト指向などの大きな成果のおかげで プログラムの生産性が向上するとともに、従来では考えられなかった 複雑なソフトウエアが作られるようになった。 しかし、プログラミング言語の進歩の速度は、必ずしも速いものではなかった。
一方で、パーソナルコンピュータのハードウエアは、最近10年程度の間に 飛躍的な機能向上を果たしている。 これは IBM が標準的アーキテクチャを公開したことに始まる。 パーソナルコンピュータを構成する個々の部品を接続する規格が公開されたことで、 部品を製造する企業が多数現れ、自由競争の原理により、 部品の高機能化・多様化が促進された。
今回開発した EPP は、言語処理系の実装方法としてよく用いられるプリプロ セッサを部品化することで、パーソナルコンピュータに起きた進歩速度の向上を、 プログラミング言語の世界にも起こすことを目的としたシステムである。 もしこのシステムのような部品化された言語処理系が世界に普及すれば、 大学や企業は新しい言語機能部品を容易に提供でき、 プログラマはその中から自分の目的に最適なものを選んで使えるようになる。 その結果自由競争の原理により、プログラミング言語の 飛躍的な高機能化・多様化が起こることを期待している。
図2は、 EPP を用いた Java プログラムの例である。 ソースファイルの先頭に #epp で始まる行を書くことで、 取り込むプラグインを指定する。 この例では "enum" という名前のプラグインを取り込むことで、 もともとの Java 言語にない enum 構文が使えるようになる。 この入力プログラムは EPP によって、図3のようなプログラムに変換される。 出力プログラムは、普通の Java コンパイラでコンパイルされ、実行可能になる。
プラグインどうしの衝突さえ起きなければ、 プラグインを複数同時に指定することもできる。 プラグインの簡単な例として、連続値定数定義、省略可能引数、マクロ定義など Java にない機能を追加するものが現在いくつか用意されている。 この中から、プログラマは自分の目的にあったプラグインを複数選択して 組み合わせて使うことができる。
現在爆発的に普及しつつある Java 言語は優れたプログラミング言語であるが、 言語機能や構文を拡張する機構を全く持たない。 EPP はこの欠点を補い、様々な新しい言語機能や、 使いやすいライブラリを提供することを可能にする。
なお、 EPP のアーキテクチャは Java 言語には依存しておらず、 他のプログラミング言語やハードウエア記述言語などにも容易に応用できる。
図1は、 System Mixin を用いたプログラムの部品と、部品を組み合わせた結果を 摸式的に表わしたものである。 一枚一枚の絵は、最終的なできあがりの絵のうち、 ある側面から見た部分(この場合は色)だけを切り出したものである。 これらをすべて重ねると、一枚の完成した絵になる。 System Mixin を用いたプログラミングでは、個々の部品は、 なんらかの機能に密接に関連する部分だけを 切り出したものになる。 部品を複数重ねることで、完成した1つのプログラムになる。
EPP に複数のプラグインを同時に取り込めるのは、この System Mixin の 機構のおかげである。 この機能により、プリプロセッサのあらゆる拡張機能を、 オリジナルのプログラムに対する「追加部品」の形で記述することができる。
EPP は、部品の追加によって広い範囲の文法拡張が行なえるような 設計になっている。 構文解析器は、 yacc などのパーザジェネレータを使わず、 再帰下降のスタイルで直接プログラムされている。 この構文解析器には、新しい構文や演算子を追加するための簡単な「しかけ」が 数多く仕組まれており、プラグインはそれを用いることで文法を拡張できる。
EPP ではこの問題を避けるため、トークンと抽象構文木に、 処理対象の言語に依存しないような非常に汎用性の高い構造を持たせた。 このことも、複数の言語拡張プラグインを同時に適用できる理由の1つに なっている。
1. 記述言語に Java を用いる。 2. System Mixin の機構を用いる。 3. 拡張性を考慮した内部構造を持つ。しかし、アーキテクチャ全体を実行速度に配慮して設計した結果、 最新のパーソナルコンピュータで約5000行のソースコードの処理が 20秒以下となり、実用に耐え得る実行速度であると考えている。
#epp "enum" public class EnumTest { enum {RED, GREEN, BLUE} enum { MALE, FEMALE, } public static void main(String argv[]){ System.out.println(EnumTest.RED); } } 図2: EPP を使ったプログラム例
/* Generated by EPP 1.0beta3 (by lisp-epp1.0beta3) */ public class EnumTest { public static final int RED = 0; public static final int GREEN = 1; public static final int BLUE = 2; public static final int MALE = 0; public static final int FEMALE = 1; public static void main(String argv[]){ System.out.println(EnumTest.RED); } } 図3: 変換結果