正直、中で何をしているのか理解するのに時間がかかるくらいでかく複雑(に僕には見える)マクロだが、本質的な原因は以下のマクロが動かないことにあることが分かった。
(import (rnrs)) (define-syntax expand-it (lambda (x) (define (gen-return var) (with-syntax ((v var)) #'v)) (syntax-case x () ((_ (v init) expr ...) (with-syntax ((r (gen-return #'v))) #'(let ((v init)) (when (= v r) expr ...))))))) (expand-it (v 1) (display 'ok) (newline))Chezで試したが当然動く。正直、何がいけないのかすでに分かっていて、以前あったパターン変数の問題の展開された識別子版である。
入力として与えられてvが二箇所の
syntax
で展開されているためにそれぞれ別の識別子として出力されるのが問題なのである。それこそ、マクロ展開器との格闘を始めて結構長いと思うが、このパターンは完全に見落としていた。こんなマクロ書いたことないし、見たこともないからである。パターン変数の問題はいくらか書いたし、見たことがあったので何が原因かも分かっていたのだが、これは思いもよらなかった。なんというか、目の前に大穴が空いているのに全く気づかなかった気分である。
パターン変数の際と同様の方法で解決するとするか。
しかし、この1週間でマクロ展開の実装は所詮環境の参照と識別子のリネームだけなんだと痛感させられた。ただ、それが異様に面倒なだけで・・・
No comments:
Post a Comment