R7RS→R5RSへのlowerが可能なのか問題

nmoshはR7RSライブラリをR6RSに変換することでR7RSライブラリを読み取れるようにしている。同様のことをモジュールシステムの無いR5RS相当の実装、例えばMIT SchemeやSchluesselで行なってR7RSを実装できないかと思った。
つまり:

  • R7RSコードとライブラリの字面だけを見て(syntax-rulesを展開すること無く)、フラットなR5RSコードに変換することは可能か

当然、自前のexpanderを持てば実装するのは容易と言える。が、実装本来のsyntax-rulesを生かしたままこれを実装する方法は今のところ思いついていない。

手続きやオブジェクトのrenameは簡単

重要、というか、唯一の実装が必要な構成要素として、ライブラリ構文にある rename が挙げられる。renameさえ実装できれば、後はライブラリのコードを適当にrenameしつつ連結すれば、R7RSライブラリをR5RSプログラムに変換することができる(当然R7RSで定義される構文や手続きのR5RS実装も作っておく必要があるが。。)
手続きやその他オブジェクトのrenameは非常に簡単と言える。例えば、単にletでnamespacingし、最後にset!すれば目的を達成できる。

(library (A)
         (export
           (rename (a global-A)))
         (import (rnrs))
  (define a 10))

;; ↓ 変換

(define global-A #f)

(let ()
 (define a 10)
 ;; Perform rename
 (set! global-A a))
;; ここでは a は定義されていない = renameが効いている

マクロのrenameが必要?

しかし、マクロはこの方法でrenameすることができない。たぶんgenericなR7RSコードを、字面だけ見て(syntax-rules自体を展開することなく)安全にrenameすることは不可能なのではないかと思う。
ただし、本当に素のR7RSであれば、シンボルを合成する方法が無いので、エクスポート対象のシンボルを完全に追跡できればrenameも可能かもしれない。。つまり、define-library構文でexport対象とされているシンボルを走査し、それを全てユニークなシンボルに変換してしまうことが考えられる。が、これはquoteの中身等マクロ参照でないシンボルを壊すので実際には安全でない。
本当にrenameが必要なのは、グローバルスコープにdefine-syntaxされるマクロと、そのマクロから参照されるマクロだけなので、ライブラリの書き方に一定の(現実的な)制約を設けることで簡単にR5RSにlowerできるR7RSライブラリが構築できるのかもしれない。
一番簡単には、ライブラリからマクロのエクスポートを禁止することで、lower可能なライブラリを作ることができる。。これはあまり実用的では無さそうだ。
"トップレベルで直接define-syntaxしたマクロだけがエクスポートできる"というのは現実的な制約かもしれない。この制約を付けることで、ライブラリのエクスポートしているシンボルがマクロなのかオブジェクトなのかを字面を見るだけで決定できるようになる。ただし、このような制約を付けたとしても、依然マクロのrenameはtrivialではない。更に、importも含めて"マクロのrenameを禁止する"ことで、やっと実現可能性が見えてくるが。。これはprefixのようなライブラリ全体をrenameする機能と非常に食べ合せがわるい。
... もっとも、手元のSchemeアプリケーションでは、殆どマクロのrenameは使っていない。なので、何かウマい妥協点が有るような気はしている。
多分解かないといけない問題は、

  • R5RSのsyntax-rulesしか実装していない処理系で、R7RSのSRFI-46なsyntax-rulesを実装して使うgenericな方法

になる。もちろんプログラムの字面を見て静的に変換するのはOK、つまり、R7RS→R5RSトランスレータとして実装するとして、最も労力が掛からずに実装できる方法は何か?(たぶんexpanderを自前で実装するのが一番簡単だが。。)