For Gauche 0.9.10


Next: , Previous: , Up: マクロ   [Contents][Index]

5.3 伝統的なマクロ

Special Form: define-macro name procedure
Special Form: define-macro (name . formals) body …

変換子が procedure である大域マクロ name を定義します。 2番目のフォームは、以下のフォームの簡易記法です。

(define-macro name (lambda formals body …))

コンパイラが (name arg …) というフォームを見つけると、 arg … を引数として procedure を呼び出します。 procedure が戻ると、コンパイラは元のフォームの場所に返されたフォームを 挿入し、再度それをコンパイルします。

マクロによって挿入される束縛の名前衝突を避けるために、 伝統的なLispマクロと同様にgensymを使うことができます。 (シンボル参照)。

(define-macro (if-let1 var test then else)
  (let1 tmp (gensym)
    `(let ((,tmp ,test))
       (if ,tmp ,then ,else))))

(macroexpand '(if-let1 v (find odd? '(2 4 6 7 8))
                 (* v v)
                 #f))
  ⇒ (let ((#:G1013 (find odd? (quote (2 4 6 7 8)))))
              (if #:G1013 (* v v) #f))

gensymではマクロが挿入するグローバルな束縛の衝突は回避できません。 なぜ衛生的マクロかでこの点について説明しています。


Next: , Previous: , Up: マクロ   [Contents][Index]