Next: , Previous: , Up: Top   [Contents][Index]


5 マクロ

このパッケージは、分配や&environment&bodyのような defmacroのさまざまなCommon Lisp機能を実装する。トップレベルの &wholeは、技術的困難のためにdefmacroのためには 実装されない。See 引数リスト.

分配は、下記のマクロを通してユーザに利用可能になっている:

Special Form: destructuring-bind arglist expr forms…

このマクロは、arglistの中の変数がexprによって戻される値の リストに束縛されている状態で、formsを実行するコードに展開する。 arglistは、分配を含むdefmacro引数リストのために 許されるすべての機能を含むことができる(&environmentキーワードは 許されない)。マクロ展開は、exprが不正な引数の個数のリストを 戻したり、不正なキーワード引数がある場合はエラーを通知するだろう。

このパッケージは、Common Lispのdefine-compiler-macro機能も 含んでおり、コンパイル時展開の定義や関数の最適化を許す。

Special Form: define-compiler-macro name(名前) arglist forms…

このフォームは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 述語を含むその他のかなりのものを最適化する)。

Function: compiler-macroexpand form

この関数はmacroexpandに似ているが、通常のマクロではなく コンパイラマクロを展開する点が異なる。コンパイラマクロがそのために 定義された関数の呼び出しではない場合、またはコンパイラマクロがその &whole引数を戻すことでパントすることを決定した場合、form を変えずに戻す。macroexpandのように、それ以上の展開が不可能な フォームに達するまで繰り返し展開する。

macroletの記述と“局所”マクロ定義作成のための symbol-macroletフォームについては、See マクロ束縛.