たまにsyntax-rulesでも間違える
前のエントリ( http://d.hatena.ne.jp/mjt/20140914/p2 )でsyntax-rulesは得意みたいなことを書いておきながら、Gaucheはこれが違法なのに今気付いた:
(import (scheme base) (scheme write)) (define-syntax defPlusOne (syntax-rules () ((_ nam) (begin (define-syntax temp (syntax-rules () ((_ param) (+ 1 param)))) (define-syntax nam (syntax-rules () ((_ param) (temp param)))))))) (defPlusOne plus-one) (write (plus-one 1))
Gaucheはマクロをidentifierに対して定義できないように見える。
oku@spring ~/repos/yuni $ gosh h.scm *** ERROR: Compile Error: symbol required, but got #<identifier r7rs.user#temp> "./h.scm":16:(defPlusOne plus-one) Stack Trace: _______________________________________
nmoshやchibi-schemeやRacket、psyntax系の実装は期待通り2を出力する。nmoshの場合この手の記法はletrec-syntaxと等価(あまり健康でない)。
バグのような気もするが、R7RSがこれが動くことを要求しているようには読めなかった。
ちなみにGaucheもdefineのケースは問題なく動く。
(import (scheme base) (scheme write)) (define-syntax defPlusOneF (syntax-rules () ((_ nam) (begin (define temp (lambda (param) (+ 1 param))) (define nam (lambda (param) (temp param))))))) (defPlusOneF plus-one) (write (plus-one 1))
いずれにせよ奥が深い。。GaucheのようなScheme処理系に対応するには、マクロとしてgensymを用意してやる必要が有るように見える。個人的にはマクロを定義するマクロで小マクロに分割する手法としてたまに使ってしまうので、なにか上手い記法を考えたいところ。