Let's start Scheme

2011-03-05

マクロの問題

syntax-caseを実装していて困った問題に気づいた。
問題の本質を指すコード
(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