Macro DEFGENERIC

UP


Macro DEFGENERIC

Macro DEFGENERIC

構文

defgeneric function-name gf-lambda-list [[option | method-description*]]
=> new-generic

option ::= (:argument-precedence-order parameter-name+) |
           (declare gf-declaration+) |
           (:documentation gf-documentation) |
           (:method-combination method-combination method-combination-argument*) |
           (:generic-function-class generic-function-class) |
           (:method-class method-class)

method-description ::=
  (:method method-qualifier* specialized-lambda-list
   [[declaration* | documentation]] form*)

引数と戻り値

function-name - 関数名
generic-function-class - nilではない、クラス名のシンボル
gf-declaration - optimizeの宣言指定子。他の宣言指定子は許されません。
gf-documentation - 文字列(評価はされない)
gf-lambda-list - ジェネリック関数のラムダリスト
method-class - nilではない、クラス名のシンボル
method-combination-argument - オブジェクト
method-combination-name - nilではない、method-combinationの型の名前のシンボル
method-qualifiers, specialized-lambda-list, declarations, documentation, forms - defmethodに従います。
new-generic - ジェネリック関数オブジェクト
parameter-name - ラムダリスト内にある要求パラメーターの名前のシンボル。 (もし:argument-precedence-orderオプションが定義されているならば、 ラムダリスト内のそれぞれの要求パラメーターは、 parameter-nameが正確にひとつ使われなければなりません)

定義

マクロdefgenericは、ジェネリック関数を定義したり、 ジェネリック関数全体に関わるオプションと宣言を指定するときに使われます。

もしfunction-nameがリストなら、(setf symbol)の形式でなければなりません。 もし(fboundp function-name)falseのときは、新しいジェネリック関数が作成されます。 もし(fdefinition function-name)がジェネリック関数のときは、 そのジェネリック関数は変更されます。 もしfunction-nameが通常の関数か、マクロか、特殊オペレーターの名前のときは、 エラーが発生します。

defgenericマクロは、次に示す3つのステップが実行されたかのような効果を示します。 第一に、以前defgenericフォームで定義されたメソッドは削除されます。 第二に、ensure-generic-functionが呼び出されます。 そして最後に、今回のdefgenericフォームによって定義されたメソッドが、 ジェネリック関数に追加されます。

method-descriptionは、そのジェネリック関数上で、メソッドが宣言されます。 各メソッドのラムダリストは、gf-lambda-listオプションによって指定された ラムダリストと合致しなければなりません。 メソッドの定義が指定されておらず、 同名のジェネリック関数が存在しない場合は、 メソッドがないジェネリック関数が作成されます。

defgenericの引数gf-lambda-listは、 そのジェネリック関数のメソッドに対して、 ラムダリストの形を指定します。 返却されるジェネリック関数上の全てのメソッドは、 この形に合致したラムダリストを持たなければなりません。 もし、defgenericフォームが評価されたとき、 そのジェネリック関数にあるメソッドのラムダリストが defgenericフォームに付与されたものと合致しない場合は、 エラーが発生します。 メソッドの合致に関するさらなる詳細は、7.6.4. ジェネリック関数の全てのメソッドのラムダリストの合意をご確認ください。

ジェネリック関数は、渡されたすべての引数をメソッドに渡します。 渡されるのはそれらの値のみであり、デフォルト値は供給されません。 ただし、メソッド定義にはオプション引数とキーワード引数があり、 デフォルト値とsupplied-pパラメーターが使用できることに注意してください。

次に示すオプションが提供されます。 注意書きがあるもの以外、オプションはただひとつ与えられます。

引数method-descriptionは、ジェネリック関数に関連付けたメソッドを宣言できます。 メソッド宣言にある引数のmethod-qualifierspecialized-lambda-listは、 defmethodと同じです。

引数formは、メソッドのボディ部です。 メソッドのボディ部は、暗黙のblockで囲まれます。 もしfunction-nameがシンボルのとき、 blockの名前はジェネリック関数と同じ名前です。 もしfunction-name(setf symbol)のリスト形式の場合は、 blockの名前はsymbolです。

実装は、defgenericに別のオプションを含めるよう拡張できます。 もし自身が実装していないオプションが見られた場合は、 その実装はエラーを発生するよう要求されます。

defgenericは、コンパイル時にはどのような副作用も要求されていません。 特に、コンパイル時に呼び出すためのメソッドは導入されません。 実装者は、コンパイル時のエラーチェック (関数呼び出し時の引数の個数チェックであったり、 あるいは関数名の定義を確認したりすること)のために、 ジェネリック関数についての情報を保存するか選択できます。

例文

なし。

影響

なし。

例外

もしfunction-nameが通常の関数か、マクロか、特殊オペレーターの名前のときは、 型program-errorのエラーが発生します。

引数gf-lambda-listとして指定された各要求された引数は、 parameter-nameとして正確にひとつだけ含まれなければならず、 そうでないときは、型program-errorのエラーが発生します。

method-descriptionによって指定された各メソッドのラムダリストは、 gf-lambda-listオプションによって指定されたラムダリストと合致していなければならず、 そうでないときは型errorのエラーが発生します。

もし、defgenericフォームが評価されたとき、 そのジェネリック関数にあるメソッドのラムダリストが defgenericフォームに付与されたものと合致しない場合は、 型errorのエラーが発生します。

オプションがただひとつではなかった場合は、 型program-errorのエラーが発生します。

もし、function-nameが既存のジェネリック関数を示しており、 新しいジェネリック関数の:generic-function-classの値が 古いものと互換性がある場合は、 change-classが呼ばれてジェネリック関数のクラスが変更されます。 それ以外の場合は型errorのエラーが発生します。

実装は、defgenericに別のオプションを含めるよう拡張できます。 もし自身が実装していないオプションが見られた場合は、 その実装は型program-errorのエラーを発生するよう要求されます。

参考

defmethod, documentation, ensure-generic-function, generic-function, 7.6.4. ジェネリック関数の全てのメソッドのラムダリストの合意

備考

なし。


TOP, Github