問題の本質を指すコード
(define-syntax hoge (lambda (x) (er-macro-transformer (lambda (form rename compare) (display x) `(display ,form)))))一見特に問題ないように見えるが、ここで「x」はer-macro-transformerからは見えない。理由はいたって簡単で、er-macro-transformerの後ろに来たλ式は、それだけでコンパイルされるからである。でも、S式から中間式に変換する段階では見えているので、「x」は大域変数としては扱われない。束縛変数か、自由変数から探そうとしてこける。
実装の問題になると思うのだが、Sagittariusではdefine-syntaxというキーワードはマクロかクロージャのどちらかを取る様にしてある。(以前は何でも取れた)
こんなのでも、特に問題なく動く。
(define-syntax hoge (lambda (a b c d e) (+ a b c d e))) (hoge 1 2 3 4 5) ; -> 15おそらくこの辺が問題なのだと思う。
(ちなみに、クロージャが取れるようにしたのはsyntax-caseを実装するためにこの構文が必要だっただけ)
syntax-rulesもライブラリで実装している今、まじめにdefine-syntaxについて何か考えるときなのかもしれない。
R6RSでこれが問題ないならあんまり気にしなくてもいいのに↓
(define-syntax hoge (syntax-case () ((...))))あぁ、でもこれじゃwith-syntaxの実装とかできなくなるのね。というか、syntax-caseってそれ自体はたんなるマッチングみたいなのか、引数取るし。
syntax-case、かなりいいところまで行ったような気がしたけどやり直しだ・・・
No comments:
Post a Comment