Using a method option in defgeneric

When reading Keene's book, I notice that defgeneric has a parameter :method , which seems to allow you to specify a method in the most general definition. Most of the documents I've seen have all the applicable methods defined in individual defmethod s. the hyperspec with normal clarity lists :method as a parameter for defgeneric , but does not say what it means.

Does the :method parameter provide a default value, or at least a document, what do you expect from the most common use case, or does it have additional semantics? As a point of style, if you want to define only one method, does it make sense to define it in defgeneric form (if you really can) or separately in defmethod ? Or does it make no sense to do a general function in this case and use regular defun instead?

+5
source share
2 answers

The hyperspec, with its usual clarity, lists: the method as an option for defgeneric, but does not say what it means.

In fact, the HyperSpec entry for defgeneric , with its usual clarity, says exactly what that means. He says the syntax for defgeneric is:

defgeneric function-name gf-lambda-list [[option | {Description Method} *]]

and then says the syntax to describe the method:

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

And then he describes a combination method:

Each method description defines a method for a common function. The lambda list of each method should be comparable to the lambda list specified by the gf-lambda list option. If the method descriptions are not specified and a common function with the same name does not exist yet, a generic function without methods is generated.

So, the forms of a method are intended to define methods of a general function, as a form of defmethod .

(I will give that nothing is really said about why you prefer defgeneric plus: method rather than defmethod. Remember that Common in Common Lisp means that the language is an attempt to unify many existing Lisp implementations. Maybe some supported methods and others supported defmethod, and this was the easiest way to provide a unified interface.)

That is, the following effect will have the same effect:

 (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 may be convenient to define some of the methods along with a defgeneric form. It is rather a matter of style, and this applies to other parts of your question.

Does the: method parameter provide a default value, or at least document that you expect the most common use case to be, or does it have additional semantics?

This can be a kind of default if you define a method without type specifiers or using type specifiers that apply to each object (for example, t ).

As a point of style, if you want to define only one method, does it make sense to define it in definitive form (if you can, really, do it), or separately in defmethod? Or does it not make a general function in this case at all, and use regular defun instead?

I think it depends on why you expect to define only one method. If this is because you simply define the default value, but expect other users to use methods on it, then using methods together with defmethod can be convenient if someone needs to find the source. If you expect that there is only one thing, then a normal function may make more sense. I think that these decisions simply come down to choosing a style.

It is also worth noting that there are other forms that can define methods for a common function (and other forms that can also create common functions). In HyperSpec, using the up arrows to move to higher sections, you usually enter more prose. In this case, 7.6.1 Introduction to common functions is useful:

Some operators define methods for a common function. These operators will be referred to as method-defining operators; their related forms are called method-defining forms. The standardized operators that define the method are listed in the following figure.

 defgeneric defmethod defclass define-condition defstruct 
+6
source

It depends on personal preferences and how the system will be organized in the source. Or

  • simple common function: DEFMETHODS bundle

  • complex common function: a DEFGENERIC and a bunch of DEFMETHODS

  • common function: a DEFGENERIC and a bunch of methods inside

Most Lisp OO systems prior to CLOS used a single method definition form. The code may be too long in one form, otherwise common functions basically did not exist ...

When using class-oriented unidirectional systems, it would be advisable to organize methods in class definition. With the introduction of universal functions and multiple scheduling, it was advisable to organize them under the general definition of functions.

+2
source