変換子が 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ではマクロが挿入するグローバルな束縛の衝突は回避できません。
なぜ衛生的マクロかでこの点について説明しています。