Гиперспецификация со своей обычной ясностью перечисляет :method как вариант для defgeneric, но не говорит, что это значит.
Фактически, запись HyperSpec для defgeneric, с присущей ему ясностью, говорит именно то, что имеет в виду. В нем говорится, что синтаксис для defgeneric:
defgeneric имя-функции gf-лямбда-список [[опция | {метод-описание}*]]
а затем говорит, что синтаксис для описания метода:
описание-метода::= (:метод-спецификатор-метода* специализированный-лямбда-список [[декларация* | документация]] форма*)
Затем он описывает комбинацию методов:
Каждое описание метода определяет метод универсальной функции. Список лямбда-выражений каждого метода должен совпадать со списком лямбда-выражений, заданным параметром gf-lambda-list. Если описания методов не указаны и универсальная функция с таким именем еще не существует, создается универсальная функция без методов.
Таким образом, формы :method предназначены для определения методов универсальной функции, как и формы defmethod.
(Допускаю, что на самом деле ничего не говорится о том, почему вы предпочитаете defgeneric plus :method вместо defmethod. Помните, что Common в 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))
Sometimes it can be convenient to define some of the methods along with the defgeneric form. It's more a matter of style, and this gets into the other parts of your question.
Представляет ли параметр :method значение по умолчанию или, по крайней мере, документирует то, что, как вы ожидаете, будет наиболее распространенным вариантом использования, или у него есть дополнительная семантика?
Это может быть что-то вроде значения по умолчанию, если вы определяете метод без спецификаторов типа или со спецификаторами типа, которые применяются к каждому объекту (например, t).
С точки зрения стиля, если вы предполагаете определить только один метод, имеет ли смысл определять его в форме defgeneric (если вы действительно можете это сделать) или отдельно в методе def? Или вообще не имеет смысла делать дженерик-функцию в этом случае, а вместо этого использовать обычный дефун?
Я думаю, это зависит от того, почему вы ожидаете определить только один метод. Если это потому, что вы просто определяете значение по умолчанию, но ожидаете, что другие пользователи будут реализовывать для него методы, то размещение методов вместе с defmethod может быть удобным, если кому-то нужно найти источник. Если вы ожидаете, что нужно сделать только одну вещь, то обычная функция может иметь больше смысла. Я думаю, что эти решения просто сводятся к выбору стиля.
Также стоит отметить, что существуют другие формы, которые могут определять методы для универсальной функции (и другие формы, которые также могут создавать общие функции). В HyperSpec использование стрелок вверх для перехода к более высоким разделам обычно приводит к более подробной информации. В этом случае полезно ознакомиться с 7.6.1 Введение в базовые функции. :
Некоторые операторы определяют методы универсальной функции. Эти операторы будут называться операторами определения метода; связанные с ними формы называются формами определения метода. Стандартизированные операторы определения метода перечислены на следующем рисунке.
defgeneric defmethod defclass
define-condition defstruct
person
Joshua Taylor
schedule
15.04.2015