onlyに御用心(補助キーワードもexportする理由)

先日、(shorten)にonlyを足したら正常に動かなくなってしまった。

この変更を適用したあと、Chez Schemeで試してみると、

prism:lib oku$ petite
Petite Chez Scheme Version 8.0
Copyright (c) 1985-2010 Cadence Research Systems

> (import (shorten)) ;; ← 問題なくloadできているのでonlyは十分に見える
> (^a 'bogus a)
#<procedure> ;;← 正常に動いている。(lambda (a) 'bogus a)の意味
> (^a a)
Exception: invalid syntax (^a a) ;; ← おかしい (lambda (a) a)のはずなのに。。
Type (debug) to enter the debugger.
> 

のようになってしまう。
これは、 ... をonlyに含め忘れてしまっていたのが原因。

これで直る。
上で、(^a 'bogus a)が正常に動いて、(^a a)が正常に動かないのは、...をimportしないと...がsyntax-caseにとって...に見えない(!)ため。つまり、...をimportしない状態で...を使うと、...というパタン変数として扱ってしまう。
もっとも、この問題は常に発生するわけではないのが難しい。うまい説明ができないが、datum→syntaxでコードを挿入するときに使うテンプレートが...の事を知らないと、...を別の変数にリネームしてしまう。
通常のシチュエーションでは、このようなリネームには害は無い。aというシンボルがbにリネームされたとして、元のソースコードでaと書かれているところが全てbにリネームされていれば、プログラムの実際的な動作は変わらない。しかし、補助キーワードだけは別で、勝手にリネームされると困る。
free-identifier=?が成立するためには、どちらの識別子も束縛されていなくて字面上の表現が一致しているか、同じ束縛に帰着しないといけない。syntax-case的なリテラルはfree-identifier=?的な意味で一致しているかどうかを検査するし、(rnrs syntax-case)は...をexportするために...を束縛してしまっているので、free-identifier=?が成立する...を書くためには(rnrs syntax-case)から...をimportするしかない。
これは地味に難解。。自分でもexpanderを書いてなかったら分からなかったと思う。