自由変数の決定(その3)
前回までの投稿で、Scheme(Gauche)ではレキシカルスコープが使われていることが分かった(たぶん)。そもそも、自由変数がどう決定されるのかを調べ始めるきっかけは、Schemeのマクロ内の自由変数がどう扱われるかをみるためだったので、それについても書いておく。
Schemeでは、マクロの定義方法として、define-syntaxを用いる方法と、define-macroを用いる方法があるが、この二つでは、自由変数の扱いが異なっている。
例えば、
(define-syntax stx (syntax-rules () ((_) (print var)))) (define-macro (mcr) `(print var)) (define var 2) (stx) ;=> 2 (mcr) ;=> 2 (let ((var 4)) (stx)) ;=> 2 (let ((var 4)) (mcr)) ;=> 4
となり、define-syntaxを使った時は、自由変数がマクロ定義場所の環境に従って決定されているが(健全)、define-macroを使うと、マクロ使用場所の環境で自由変数が決定されている(不健全)。
僕的には、マクロがS式を生成する機能である以上、define-macroの方が自然だと思うけど、define-syntaxの方がバグが起きにくいとも思う。