このパッケージは、分配や&environment
、&body
のような
defmacro
のさまざまなCommon Lisp機能を実装する。トップレベルの
&whole
は、技術的困難のためにdefmacro
のためには
実装されない。See 引数リスト.
分配は、下記のマクロを通してユーザに利用可能になっている:
このマクロは、arglistの中の変数がexprによって戻される値の
リストに束縛されている状態で、formsを実行するコードに展開する。
arglistは、分配を含むdefmacro
引数リストのために
許されるすべての機能を含むことができる(&environment
キーワードは
許されない)。マクロ展開は、exprが不正な引数の個数のリストを
戻したり、不正なキーワード引数がある場合はエラーを通知するだろう。
このパッケージは、Common Lispのdefine-compiler-macro
機能も
含んでおり、コンパイル時展開の定義や関数の最適化を許す。
このフォームはdefmacro
と似ているが、コンパイル時にだけ
nameへの呼び出しへ展開される点が異なる; Lispインタプリタで
処理される呼び出しは展開されず、macroexpand
関数によっても
展開されない。
引数リストは&whole
キーワードと変数で始まってもよい。この変数は
マクロ呼び出しフォーム自身に、すなわちフォーム
‘(name args…)’のリストに束縛される。
マクロエクスパンダがこのフォームを変えずに戻す場合、コンパイラは通常の
関数呼び出しとして扱う。このことは、コンパイラマクロが、複雑な
場合はそのままにしながら、関数の特殊な場合のためのオブティマイザとして
働くことを許す。
たとえば、これはこのパッケージの標準部分として現れる単純化された定義の 版である:
(define-compiler-macro member* (&whole form a list &rest keys) (if (and (null keys) (eq (car-safe a) 'quote) (not (floatp-safe (cadr a)))) (list 'memq a list) form))
この定義は、aが浮動小数点定数ではないような普通の場合に、
(member* a list)
をより速いmemq
の呼び出しへ
変えることを引き起こす; aがその他の場合か、呼び出しにキーワード
引数がある場合、オリジナルのmember*
呼び出しはそのまま残る
(実際のmember*
のためのコンパイラマクロは、共通の:test
述語を含むその他のかなりのものを最適化する)。
この関数はmacroexpand
に似ているが、通常のマクロではなく
コンパイラマクロを展開する点が異なる。コンパイラマクロがそのために
定義された関数の呼び出しではない場合、またはコンパイラマクロがその
&whole
引数を戻すことでパントすることを決定した場合、form
を変えずに戻す。macroexpand
のように、それ以上の展開が不可能な
フォームに達するまで繰り返し展開する。
macrolet
の記述と“局所”マクロ定義作成のための
symbol-macrolet
フォームについては、See マクロ束縛.