[Gauche-devel-jp] Re: syntax-rulesのリテラルの解釈について

Back to archive index

Shiro Kawai shiro****@lava*****
2005年 5月 15日 (日) 10:34:36 JST


hygienicマクロは、動機は単純なんですが、厳密に定義しよう
とすると底無し沼って感じですね。
Gaucheの実装もエッジケースで怪しいところが結構あります。

で、問題の一致条件ですが、これはhygienicマクロの前提である、
「マクロ展開で使う識別子は、マクロ定義時のものである (従って、
マクロ使用時の環境と干渉しない)」という命題の特殊な場合と
考えられます。

マクロ定義時の環境とマクロ使用時の環境が異なっていたら、
識別子の意味も異なるということです。

;; 例1
(let-syntax ((m (syntax-rules (XX)
                  ((m XX) 'x)
                  ((m v) v))))
  (m XX))
==> x

この場合、
 マクロmの定義時のXXの束縛: 無し(グローバル)
 マクロmの使用時のXXの束縛: 無し(グローバル)
なので、XXの意味は同じです。


;; 例2
(let ((XX 3))   ;; [1]
  (let-syntax ((m (syntax-rules (XX)
                    ((m XX) 'x)
                    ((m v) v))))
    (m XX)))
==> x

この場合、
 マクロmの定義時のXXの束縛: [1]で束縛されている
 マクロmの使用時のXXの束縛: [1]で束縛されている
なので、やはりXXの意味は同じです。


;; 例3
(let ((XX 3))  ; [1]
  (let-syntax ((m (syntax-rules (XX)
                    ((m XX) 'x)
                    ((m v) v))))
    (let ((XX 5)) ; [2]
      (m XX))))
==> 5

この場合、
 マクロmの定義時のXXの束縛: [1]で束縛されている
 マクロmの使用時のXXの束縛: [2]で束縛されている
なので、マクロシステムは「ふたつのXXは表記は同じだけど、
意味が違う。だから別の識別子として扱おう。」と考えます。
別の識別子なんで、mの定義でXXに与えられた特別な意味(リテラル
識別子)はmの使用時のXXには及ばないのです。


;; 例4
(let-syntax ((m (syntax-rules (XX)
                  ((m XX) 'x)
                  ((m v) v))))
  (let ((XX 5)) ; [1]
    (m XX)))
==> 5

この場合、
 マクロmの定義時のXXの束縛: 無し (グローバル)
 マクロmの使用時のXXの束縛: [1]で束縛されている
なので、やはりふたつのXXは別のものとして扱われます。


--shiro



Gauche-devel-jp メーリングリストの案内
Back to archive index