Lispのマクロオブジェクトとは、CARがmacroであり、CDRが関数であるリストのことです。マクロの展開は、マクロ呼び出し時の未評価な引数のリストに対して、その関数(applyを引数として)を適用することで行われます。
匿名関数と同様に、匿名Lispマクロを使用することも可能ですが、mapcarのような関数に匿名マクロを渡すことは意味をなさないため、実際にそのようなことは行われません。実務上、すべてのLispマクロには名前が付いており、ほぼ常にdefmacroマクロを用いて定義されています。
defmacro は、シンボル name(引用符で囲まないこと)を、次のような形式のマクロとして定義します:
(macro lambda args . body)
(なお、このリストの CDR はラムダ式です。) このマクロオブジェクトは name の関数セルに格納されます。 args
の意味は関数の場合と同じで、キーワード &rest と &optional を使用できます(引数リストの特徴 を参照)。 name も
args もクォートしてはいけません。 defmacro の戻り値は未定義です。
doc が存在する場合、マクロのドキュメント文字列を指定する文字列である必要があります。declare が存在する場合、マクロのメタデータを指定する declare 形式である必要があります(declare 形式
を参照)。なお、マクロは対話的に呼び出すことができないため、対話的な宣言を行うことはできません。
マクロでは、定数と非定数部分を組み合わせて大規模なリスト構造を構築する必要があることがよくあります。これを容易にするには、「`」構文(Backquoteを参照)を使用してください。例えば:
(defmacro t-becomes-nil (variable)
`(if (eq ,variable t)
(setq ,variable nil)))
(t-becomes-nil foo)
≡ (if (eq foo t) (setq foo nil))