K2NR.ME

このエントリーをはてなブックマークに追加 Tweet

マクロ機能が存在すればいいというわけではない

どうもLisp教信者です。

HaskellにはTemplate Haskellありますし、Scalaにもマクロあるらしいですね。確かElixirにもマクロあるという情報を聞いた気がします。 マクロ、つまり抽象構文木にアクセスする機能を実装している言語ってのはたくさんあるんですが、Lisper的観点から見解を述べます。

プログラミング言語というのはソースコードのコンパイル過程で大体において抽象構文木と呼ばれるデータ構造を中間データとして出力します。 マクロはこの抽象構文木にアクセスして書き換えを可能とすることで、普通にコード書いてたんじゃ実現できないような機能を(ある意味コンパイラ機能を拡張することで)実現できます。

で、ソースコードから出力された抽象構文木にアクセスする機能なので、マクロのコードはすごく読みづらいんですね。普通のコードとは違うんです。マクロ専用の書き方がたくさんあるんです(いやあまり詳しくない状態で書いてますが)。詳細は各言語のマクロの書き方を勉強してもらえばと思いますが、その言語に慣れた人からしても新世界としか思えないような世界が広がることでしょう。

一方でLispにおいては、Lispの同図像性(Homoiconicity、いわゆるCode as Data)な性質のおかげで普通のLispコードとマクロの間にあまり差がありません。ただリストのデータを受け取って別のリストを返すだけです。

マクロ機能が存在すれば、Lispに近い、あるいは同等の柔軟性が言語にもたらされます。しかし、それとマクロが書きやすいかどうかというのは別問題です。マクロと普通のコードの書き方が違えば違うほど、学習は大変ですしバグが出た場合のデバッグも大変になります。ハードルが高くなるほど使用者は減るし、それは活かしたライブラリもあまり登場しないでしょう。

Lispにおけるマクロは同図像性の存在と組み合わせることで最大の価値がもたらされるのであってマクロだけを取り出して他言語に適用しても十分な効力は得られません。

本記事は「Lispにはマクロというのがあって…」という話をしたところ「それHaskellにもScalaにもあるよ」と返されたためカッとなって書きました。

comments powered by Disqus