同時に挿入された識別子

Scheme のローカルマクロについて知った性質があるのでメモしておく。

例えばこのようなプログラムが有った場合に画面に表示されるのは 1, 2, 3 の内のいずれだろうか。 私は 1 が表示されるものと思ったのだが、 3 が正しい挙動とのこと。

(import (scheme base)
        (scheme write))

(define-syntax bar
  (syntax-rules ()
    ((_ m body)
     (let ((m 1))
       (body)))))

(define-syntax foo
  (syntax-rules ()
    ((_ m body)
     (let ((n 2))
       (let-syntax ((%body
                     (syntax-rules ()
                       ((_) body))))
         (bar m %body))))))

(let ((n 3))
  (display (foo n (display n))))

マクロ foo を使用するとき、通常であればふたつの n は同時に挿入されたものと考えてしまうが、片方をローカルマクロに通すと別物になってしまうのだ。 もちろん使用時の環境は保存されるので foo を使用したときの環境で n は解釈されて 3 となる。

色々と変なマクロも書いたつもりだったが、知らない性質はまだまだ有るようだ。

Document ID: 7eb1ed5bc19a8cc5d37f33445918a8bc