私は以前の記事で識別子が束縛を持つかどうかを判定するマクロを書きました。 更にコードを整理しなおして Github に置いています。
具体的な判定は手続きとして切り出してしまったので、マクロ定義の側はそれを呼出しているだけです。
(define-syntax bound?
(lambda(ctx)
(syntax-case ctx ()
((_ id)
(identifier-bound? #'id)))))
bound?
の実体はほぼ identifier-bound?
に投げなおしていることがわかると思います。
このとき興味深いことがありました。
このマクロ bound?
がプログラムで使われるとき、渡される識別子のフェイズは 0 です。 identifier-bound?
はフェイズ 1 として import
しますから、 identifier-bound?
の中で他の識別子 (を表す構文オブジェクト) と比較するときにはその識別子は (meta -1)
としておくことで 1 から -1 して 0 になり、フェイズ 0 の識別子と比較するのに適切な状態となります。
この場合は処理の都合上、 datum->syntax
syntax
quote
と比較しているので、これらは (meta -1)
として import
する必要がありました。
マイナスのメタレベルが存在しうるということは知っていたのですが、自分が書いたプログラムの中に現れたのは初めてなので面白い体験でした。