メタプログラミングに関するあれこれ

wikipedia:メタプログラミング とかを見るかぎりだと『機械的なプログラム生成』という共通項はあるんだけど、それって定義が物凄く広いですよねという話をしてみる。
自分としては Javaソースコードを生成する JavaCC は、メタプログラミングという範疇で捉えていたりする。あるいは C++ のマクロとかテンプレートとか。

すると、とりあえずメタプログラミングは3種類に分けられそう。

  1. コンパイル前に処理するもの
  2. コンパイル時に処理するもの
  3. ランタイムに処理するもの

ついでにもうひとつ、ここでも分けておきたい区分がある。

  1. マクロやテンプレート等で動作が explicit に指定されるもの
  2. Convention over Configuration で動作が implicit に指定されるもの

この2つの区分法の組み合わせによってメタプログラミングは6種類に分類できるはず。たぶん。


分類の話はそれくらいでいいや。次は問題点についての話。以下、メタプログラミングのメタ部分を上層、扱う生産物を下層と定義〜。
メタプログラミングの問題点は、つまり『鏡を見てネクタイを締める』感覚にあると思いますよ。上層を意識してメタプログラミングしたいのにも関わらず、現実には下層も意識しなければならない場合が殆どです。というよりむしろ下層の処理を機械的に記述するために上層を増設したのであって、処理で最も考えるべきなのは上層ではなく下層です。つまり鏡の中の自分ではなく鏡の外の自分を『鏡越しに遠隔操作』する点がメタプログラミングの難点でしょう。
例外トレースが読みにくくなる点も同じ原因から発生しているはず。高度に洗練されたメタプログラミング手法では、例えば関数のインライン化などに代表される、下層が上層によってほぼ完全に覆い隠されてしまうような構造になっている。インライン化はつまりコンパイルタイム*1メタプログラミングだと考えることができるよね。けどインライン化手法について疑問を持っている人はあまりいない。下層が意識しなくて済むのならば、それで十分だ。


メタプログラミングは、下層を扱うことを考えるがために、下層と上層の2つの知識が必要となってしまう、というジレンマを抱えているんじゃないかなぁ。


cf: メタプログラミングの光と影 - yvsu pron. yas

*1:あるいはランタイム