Gauche:explicit renamingとマクロ展開時計算

Gauche:explicit renamingとマクロ展開時計算

Shiro(2014/08/17 16:40:39 UTC): GaucheはいずれExplicit renamingマクロを 基本においてマクロシステムを書き直す予定でいたけど、Explicit renaming だけだとうまく扱えなさそうなケースが出てきたのでメモ。

衛生マクロのキモは、識別子を「マクロ使用時の環境で解釈する」のか 「マクロ定義時の環境で解釈する」のか区別することだ。 Explicit renamingでは、シンボルそのままなら使用時環境での解釈に任せ、 定義時環境で解釈したいものだけ印をつける (rename手続きを通す) とする。 マクロでソースの字面だけを見て(=実行時の値を一切参照せずに)式変形を行うなら、これで十分だ。

ところが凝った最適化の領域に足を踏み入れると、マクロ展開器内で 値のドメインにアクセスしたいことがある。部分式を、その値が実行時にも変わらないという 仮定のもとにコンパイル時にわかってる値を使って評価するとか。リテラルだけ扱うなら 簡単なのだけれど、define-constantやdefine-inlineで定義されてる変数は 変わらないことが前提なんで、そういったものもコンパイル時に使えるなら使いたい。 そのためには、マクロの入力フォーム中のある変数が定数として束縛されてるかどうか 問い合わせる必要がある。

で、こういうことをしようとすると、マクロ展開器内で「マクロ使用時の環境で この変数についてわかっている属性」とかを知りたくなるのだけど、 Explicit remanmingでは展開器が使用時環境を基本的に触らない。 rename手続きを通すことによって、定義時環境の情報を何らかの形で付加することはできるのだけれど、 使用時環境についてはマクロ展開器がフォームを返した後で、コンパイラ本体の方で 考慮されることになる。

展開器内で使用時環境について問い合わせ可能にするには、syntactic closureのように 使用時環境をopaqueなデータとして直接渡すのが簡単だ。ただ、環境情報って コンパイラの内部構造なんで、何でもできるマクロ展開器側に渡しちゃうのは ちとおっかないんだよなあ。

implicit renamingのようにinject手続きを展開器に渡して、 識別子に使用環境を付加できるようにすれば、使用環境での束縛情報を問い合わせることは できるようになる。Chickenみたいにいろんなマクロシステムを用意して 必要に応じて使い分けてね、でもいいんだろうけど、 ベースとなるシステムは統一されてた方がわかりやすいしなあ。

More ...