# [no subject]

• To: Bobrow.pa@XEROX.COM
• From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET
• Date: 23-Jan-87 15:15:45
• Cc: common-lisp-object-system@SU-AI.ARPA

Subject: Re: New version of define-method-combination

The following is an alternate version of define-method-combination.
It has the following properties:

1) There is only one define-method-combination form. It allows easy
support of around methods, and supports error checking.  Defining simple
combinations is easy and concise.
Sounds good to me.

2) There is no lambda-list.  It also omits the keyword :order from the
method specifier.  defgeneric-options is extended to store parameters
in the generic function. This can be used to support features like
reversed order for <and> combination if desired.

There is a problem in tying up the parameters of the method combination to the generic function.
If the user has to access those from the generic function, extensions where there
can be several method combinations defined for the same generic function will not work.
Parameters passed explicitly to the method combination function avoid this problem.

4) It uses the keyword :call-next-method instead of :around in
make-method-call.   This eliminates confusion with respect to use of
this keyword  with primary methods, and with respect  to the new :around
keyword in method-combination options used to support around methods.
Thus
(make-method-call primary :around t)
becomes
(make-method-call primary :call-next-method t)
This renaming needs to be carried through to the functi
chapter.
I don't have any feeling for this one.

Text that looks similar to that in the concep chapter was in fact taken
from there, and no changes were made in most paragraphs.

I am recommending that we include this instead of the
current version in concep.

The rest of the message (TEX source) is painful to read.

*** Extension to defgeneric-options

defgeneric-options

{\bf :method-combination }

The list that is cdr of the option form is stored
in the generic-function object in the slot
{\it method-combination\/}.
Example:
(:method-combination and :most-specific-last)
stores {\it (and :most-specific-last)\/} in the slot
{\it method-combination\/}.

The body of compute-effective-method can get this information
from the generic-function using the slot-accessor.

***

*** Alternate version of define-method-combination***

\beginSection{Declarative Method Combination}
\beginsubSection{Defining Form for Method Combination}

The programmer can define new forms of method combination using the {\bf
define-method-combination} macro.  This allows customization of step~3
of the method combination procedure.  The body of {\bf
define-method-combination\/} used resembles {\bf defmacro\/} in that the
body is an expression that computes a Lisp form, usually using
backquote.  Thus, an arbitrary combination  of methods can be
constructed.

%The following syntax expressions need to be converted to TEX

(DEFINE-METHOD-COMBINATION name 	                     [macro]
({method-group-specifier}+ )
[({method-combination-option}*)]
{form}*)

{method-group-specifier}:= (variable { {qualifier-pattern}+ | predicate}
{keyword argument}*)

The method-group-specifier predicate is a good thing to have.

{method-combination-option} :=combination-keyword value

{\bf :around} {\it boolean\/}
If the argument is true (not {\bf nil}),
then the form returned by the body of define-method-combination
is augmented to support :around methods.  See examples below.
This keyword option is a convenience and does not add any
expressive power. It is provided so that programmers are not
tempted to omit support for :around methods. Methods matching
(:around) are extracted first from the list of applicable
methods. If {\bf :around} is not specified, it defaults to
{\bf nil}. The argument {\it boolean\/} is not evaluated.

;The default method-combination, the hard way
(define-method-combination standard
((around (:around))
(before (:before))
(primary ())
(after (:after)))
(unless primary
(method-combination-error "A primary method is required."))
(make-method-call (,@around
(multiple-value-prog2
,(make-method-call before)
,(make-method-call primary :call-next-method t)
,(make-method-call (reverse after))))
:call-next-method t))

;The default method-combination using keyword options
(define-method-combination standard
((before (:before))
(primary () :required t)
(after (:after)))
(:around t)
(multiple-value-prog2
,(make-method-call before)
,(make-method-call primary :call-next-method t)
,(make-method-call (reverse after))))

I am not sure that the :around keyword actually simplifies things. It hides the around
mechanism, but seeing the actual code helps people to get the right model in their minds.

Despite these points, we seem to be converging on this issue.

Patrick.

`