transform環境はrun-time環境の定義を引き継ぐか

追記 :
正解は、

(import (for (some library) expand))

らしい。
追記 :
PLTではdefine-for-syntaxをつかうしか解決策は無いようだ。

バージョン 4 以降の PLT Scheme では、マクロ展開のフェーズは実行時とは別環境になるので注意が必要です。例えばマクロ展開時にライブラリ関数を使いたい場合は (require (for-syntax ... )) として読み込む必要があります。

要するにポータブルな方法は無いように思える。

以前の内容

昨日の、

(import (rnrs))

(define (tx x) (+ 1 x))
(define (tp p)
    (syntax-case p ()
      ((k arg)
       (datum->syntax (syntax k) (tx (syntax->datum (syntax arg)))))))

(define-syntax tt tp)

(display (tt 2))(newline)

の続き。PLTはmoshと同様の動作となった。

expand: unbound identifier in module (in the transformer environment, which does not include the run-time definition) in: tp

つまり、

  • ikarus, ypsilon : コードのexpand中に実行時環境を既に持つ
  • mosh, mzscheme : expand中の環境と実行時の環境は分離されている

通常のシチュエーションにおいてexpand環境にシンボルを持ち込むには(知る限り)ライブラリにしなければならない*1。つまり、

  • support.sls
(library (support)
         (export tp)
         (import (rnrs))

(define (tx x) (+ 1 x))
(define (tp p)
    (syntax-case p ()
      ((k arg)
       (datum->syntax (syntax k) (tx (syntax->datum (syntax arg))))))))

と、

  • main.scm
(import (rnrs) (support))
(define-syntax tt tp)

(display (tt 2))(newline)

のようにプログラムを分割すれば全てPLT以外の実装で望む結果を得る。

*1:define-syntax中で使えるlambdaやsyntax等の名前がどこから来たのかを考えれば。。