コンパイルタイムプログラミング

10年ほど前に書いたプログラムを不意に見付けた。 アセンブリ言語を用いたものだ。 masm を使うことを想定して書かれている。 (実際には互換性のある NOWSMART ASSEMBLER を使っていたのだが。) その中にちょっと面白いと思った部分があった。

L	EQU	5
line	dd	0
I	=	1
	rept	L
	dd	I DUP(I)
I	=	I+1
	endm

これは以下のように書くのと同じだ。

line	dd 0,1,2,2,3,3,3,4,4,4,4,5,5,5,5,5

当時は全く不自然に思わずアタリマエに使っていたが、よく考えるとぜんぜんアタリマエでは無い。

例えば C のマクロで実現しようとすれば相当につらい思いをすることだろう。 C のマクロでは繰り返しや再帰を直接に表現することは出来ないからだ。 #include をネストする等の方法で無理するしかない。

C++ のテンプレートはかなり強まっていて似たようなことは出来るが、それでも配列を作るのは出来ないと思う。

[追記]
江添氏が C++ で書いてくれた。
http://cpplover.blogspot.jp/2010/12/c0x.html
[/追記]

そう考えると CommonLisp や Scheme (r6rs以降) のマクロは滅茶苦茶に強力だとあらためて思う。 ランタイムに出来る大抵のことはコンパイルタイムに出来るんだから。

Document ID: 0bbc6eaf7f14e85ea3d8eea15c7f581c