ハイパースペックは、通常の明確さで、defgeneric のオプションとして :method をリストしていますが、それが何を意味するかは述べていません。
実際、 defgeneric のHyperSpecエントリは、通常の明快さで、それが何を意味するかを正確に示しています。defgeneric の構文は次のとおりです。
defgeneric 関数名 gf-lambda-list [[オプション | {メソッドの説明}*]]
method-description の構文は次のとおりです。
メソッドの説明::= (:method メソッド修飾子* 特殊ラムダリスト [[宣言* | ドキュメント]] フォーム*)
そして、method-combinationについて説明します:
各メソッド記述は、ジェネリック関数のメソッドを定義します。各メソッドのラムダ リストは、gf-lambda-list オプションで指定されたラムダ リストと一致する必要があります。メソッドの説明が指定されておらず、同じ名前のジェネリック関数がまだ存在しない場合は、メソッドのないジェネリック関数が作成されます。
したがって、:method フォームは、defmethodフォームと同様に、ジェネリック関数でメソッドを定義するためのものです。
(defmethod ではなく defgeneric と :method を好む理由については、実際には何も述べていないことを認めます。Common Lisp のCommonは、言語が多くの既存の Lisp 実装を統合する試みであることを意味することを思い出してください。多分:method をサポートするものもあれば、defmethod をサポートするものもあり、これが統一されたインターフェイスを提供する最も簡単な方法でした。)
つまり、以下は同じ効果があります。
(defgeneric to-list (object))
(defmethod to-list ((object t))
(list object))
(defmethod to-list ((object list))
object)
(defgeneric to-list (object)
(:method ((object t))
(list object))
(:method ((object list))
object))
defgeneric 形式でいくつかのメソッドを定義すると便利な場合があります。それはスタイルの問題であり、これは質問の他の部分に入ります。
:method オプションは、デフォルト、または少なくとも、最も一般的なユースケースが予想されるドキュメントを提示しますか?それとも追加のセマンティクスがありますか?
型指定子なしでメソッドを定義する場合、またはすべてのオブジェクトに適用される型指定子 (たとえばt ) を使用してメソッドを定義する場合、これは一種のデフォルトになる可能性があります。
スタイル ポイントとして、メソッドを 1 つだけ定義すると予想される場合、それを defgeneric 形式で定義すること (実際にそれができる場合) と、defmethod で個別に定義することのどちらがより理にかなっていますか? それとも、この場合ジェネリック関数を作成し、代わりに通常の defun を使用するのは意味がありませんか?
メソッドを1つだけ定義する理由に依存すると思います。デフォルトを定義しているだけで、他のユーザーがそれにメソッドを実装することを期待している場合、ソースを見つける必要がある場合は、メソッドを defmethod と一緒に配置すると便利な場合があります。やるべきことが 1 つだけだと予想される場合は、通常の関数の方が理にかなっている可能性があります。これらの決定は、スタイルの選択に帰着すると思います。
ジェネリック関数でメソッドを定義できる他のフォーム (およびジェネリック関数を生成できる他のフォーム) があることも注目に値します。HyperSpec では、上矢印を使用してより高いセクションに移動すると、通常、より多くの散文が表示されます。この場合、7.6.1 ジェネリック関数の紹介が役に立ちます。
一部の演算子は、ジェネリック関数のメソッドを定義します。これらの演算子は、メソッド定義演算子と呼ばれます。それらに関連付けられたフォームは、メソッド定義フォームと呼ばれます。標準化されたメソッド定義演算子を次の図に示します。
defgeneric defmethod defclass
define-condition defstruct