問題となるのは以下のようなコード。
(import (rnrs)) (define-syntax renaming-test (syntax-rules () ((_ var val) (begin (define dummy val) (define (var) dummy))))) (define dummy #f) (renaming-test a 'a) (print (a)) (print dummy)まぁ、見れば分かるとおり、最後のdummyは#fを返してほしいのだがaを返してくるというバグである。要するにリネームが上手いこといっていないのである。
現状ではリネームは展開時にのみ行われているのだが、パターンのコンパイル時にどこにも束縛されていない識別子はリネームしてしまっていいのではないか?という気がしている。上記の例なら、パターン変数であるvarとval、束縛されている_、begin及びdefineはリネームするとまずいのだが、残り(dummy)はリネームしてもマクロ外にもれることはないわけなのだから(むしろ漏れるとまずい)。ちょっとそんな感じでやってみるかね。 あぁ、だめだ。それだと以下のようなパターンで困る。
(let ((dummy #f) (hoge #t)) (define (print . args) (for-each display args) (newline)) (let-syntax ((renaming-test (lambda (x) (syntax-case x () ((_ var val) #'(begin (define dummy val) (define (var) dummy) (display hoge) (newline))))))) (renaming-test a 'a)) (print (a)) (print dummy))これだと、dummyはリネームされてほしいけど、hogeは変更されたくない。ただ、このパターンってマクロが構文を知ってないとどうしようもないような。違うかな?dummyとhogeが意味的に違うってのを構文の情報なしにどう知ればいいんだ?
No comments:
Post a Comment