バグの報告は以下のツイート
Sagittarius 0.6.8 でこれが期待と違う結果になる。
R7RS の方で動作させると (1 2 3) が出力されるけど、 R6RS の方では (3 3 3) が表示された。 pic.twitter.com/QBQbsMf0tP
— 齊藤敦志 (@SaitoAtsushi) October 8, 2015
突き詰めていくと、テンプレート変数を割り当てていく部分で使用しているfree-identifier=?
がこの条件だと全ての一時パターン変数に対して#t
を返すということが分かった。adhocに直すならこういう場合の比較に対しては#f
を返すようにすればいいのだが、コードを眺めていてふと思った、「こいつらbound-identifier=?
で比較しないとまずくね?」と。単純にこの二つの手続きを置き換えるだけなら何の問題もなく、こんな記事も書いてはいないのだが、そうは問屋が卸してくれなかった。問題になるのは、
with-syntax
等でラップされた式の中で束縛されたテンプレートを返すようにした場合である。例えばこんなの:(syntax-case x () ((_ (k ...)) (with-syntax (((e ...) (gen))) #'(lambda (x) (syntax-case x (k...) e ...)))))具体的には
syntax-rules
がこんな感じの定義なんだけど、パターン変数がそのままマクロによって生成されるsyntax-case
で使われているのがまずい。現状の実装ではマクロの展開が走ると問答無用で識別子がリネームされてしまうので、パターンのkとテンプレートのkが別の識別子として束縛されてしまう(つまりbound-identifier=?
が#f
を返す)。あれ、待てよ。パターン変数として束縛された識別子はマクロ環境で束縛されているので、リネームの際にそれを避けるようにすれば無用なリネームが発生しないことになるな。その方向でいくか。やはり問題は一度書き出すとなんとなく解決策がでてくるものだな。まだ解決してないけど。
No comments:
Post a Comment