explicit renaming占い

ここで定義されているlet/scopeマクロは、"定義位置に引数をbeginで囲って展開する"という動作をしている。
これが期待通り動作しないのはマクロの合成問題( http://d.hatena.ne.jp/mjt/20141011/p1 )と言える。便宜上このように番号を振ると:

(let ((x 1)) ;; ← ★ x:1
  (let/scope scope-1  ;; ← ★ scope-1:1
    (let ((x 2)) ;; ← ★ x:2
      (let/scope scope-2
        (let ((x 3)) ;; ← ★ x:3
          (let/scope scope-1 ;; ← ★ scope-1:3
            (let ((x 4)) ;; ← ★ x:4
              (display (scope-2 (scope-1 x)))
              (display (scope-2 x))
              (display (scope-1 x))
              (display x))))))))

displayの並びは

(display (scope-2 (scope-1:1 x:2))
(display (scope-2 x:2))
(display (scope-1:3 x:3))
(display x:4)

のようになることが期待される(おそらくGaucheの動作は何か間違っている)。
つまり、"(display (scope-2 (scope-1 x)))"のscope-2を展開するときにscope-1だけではなくxもx:2にリネームされてしまうため、仮にscope-1の位置に挿入したとしても、直上のx:1にはマッチしない。
... 次の問題は、期待通りの動作をするlet/scopeをer-macroで(補助マクロを導入することなく)実現できるかというポイントになるが、今のところ良い方法が思いあたらない。
chibi-schemeの場合はidentifier→symbolを提供しているので、R6RSのsyntax→datumのように一旦文脈情報を取り去った上でrenameする手が有る。

(define (traverse0 proc obj) ;; traverse0に改名しておく。また、chibi-schemeにはidentifier?が有るので適合するようにid?を変えておく。
  (let loop ((obj obj))
    (cond ((id? obj)     (proc obj))
          ((pair? obj)   (cons (loop (car obj)) (loop (cdr obj))))
          ((vector? obj) (vector-map loop obj))
          (else obj))))

(define (strip sexp) (traverse0 identifier->symbol sexp))
(define (traverse proc obj) (traverse0 proc (strip obj)))

つまり、他の処理系では他の対策が必要になることになる。
R7RS largeではer-macroを標準にすることを意図していると思うけど、この辺を統一しておかないとあまり役に立たない気がする。そもそも、単純にシンボルを連結するようなマクロでもポータブルに書けないのは困るので、何か見落しているのかもしれない。(このidentifier?問題のために、nmoshでは移植性ライブラリであるyuniに専用のシンボル連結構文を入れている( http://d.hatena.ne.jp/mjt/20140914/p1 )。)