# Danny's new version of define-method-combination

• To: common-lisp-object-system@SAIL.STANFORD.EDU
• Subject: Danny's new version of define-method-combination
• From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
• Date: Wed, 28 Jan 87 00:05 EST

I said I wasn't going to think about method-combination any more this
month, but I changed my mind.  The indented messages below are excerpted to
show just enough context for my comments to make sense.  In the interests
of getting the document finished soon, for each point, after general
discussion I make a suggestion for what to do; naturally I'm more than
willing to listen to arguments that my suggestions are wrong.

Date: 20 Jan 87 12:11 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>

1) There is only one define-method-combination form.

I don't think the short form is vitally important, but until we converge
on all details of the long form it's difficult to tell how much syntactic
verboseness and error-proneness the short form will save.  I suggest that
for right now a boldface note be added to the document saying that the
short form is still under discussion and there is a good chance it will
go away in a future revision.

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.

I agree with Patrick's argument that storing parameters in the generic
function won't work.

There is a more general philosophical issue here.  Symbolics has agreed to
the approach of making a lean proposal, containing only features that are
truly necessary and that are well-understood.  One can see from reading the
document that this policy hasn't been carried out perfectly uniformly, but
it's the direction we're aiming.  There are a number of extensions that we
feel are important in the industrial real world, but that we agree don't
belong in the standard right now.  If these extensions prove worthwhile,
they might be implemented by individual implementations and then eventually
added to the standard.  I consider it important to design the lean standard
so that such extensions can be added smoothly and painlessly, without
making incompatible changes to the original standard.  This means that some
design choices, which could go either way when considered in isolation,
need to go a certain way in order to leave room for possible extensions.
Is this agreeable to the other participants?

This is the reason for the lambda-list.  Having to say () now is relatively
painless, but adding a lambda-list in the future would be difficult.  In
fact the lambda-list also turns out to be a better way to provide access to
the generic-function object than any other I've thought of.

I would be agreeable to removing the :order keyword if a lean standard is
paramount, although it seems to add only minimal complexity and I've seen
reversed order of method specificity used quite a lot.

I suggest not changing anything here.  Alternatively, :order could be
removed.

3) It is syntactically distinguishable from the current Flavors
version of define-method-combination, and hence allows backwards
compatiblity.

Current Flavors users will bless you.

4) It uses the keyword :call-next-method instead of :around in
make-method-call.

This is okay with me.

[A later message from Danny said:]
Because :operator and :call-next-method (nee :around) cannot both
appear, I suggest that the syntax of make-method-call be

(make-method-call method-list &optional
(operator 'progn)
(identity-with-one-argument (eq operator 'progn)))

Where if operator has the value :call-next-method, it has the same
effect as previously providing that argument with t as its value.

I'm opposed to using optional arguments instead of keyword arguments,
because it makes extensibility much more awkward.  Using a special
value for the :operator argument instead of a :call-next-method
argument would be okay with me, although I suspect it will be difficult
to document in a way that does not cause confusion.

I suggest changing :around to :call-next-method here, but flushing :around
and saying :operator 'call-next-method (no colon) would be okay too.
Flushing the idea of controlling it with an argument and going back to a
second function, named make-next-method-call or something, would be okay
too.  Does anyone have a strong preference for one or another of these?

{method-combination-option} :=combination-keyword value
The list of method-combination options is optional, and is
distinguished from a form because it starts with a keyword.

We have this syntax for method-combination options in Flavors and I think
it is grotesque.  I suggest not including this.

The keyword options supported are:
{\bf :documentation} {\it string\/} documents the method-combination
type.

I don't see why we shouldn't use the same syntax as defmacro for
documentation strings.

{\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.

I comment on this below, in connection with Gregor's comments on it.

The variable {\it generic-function\/} is available in the body forms of the
combination definition.

That's how we do it in Flavors (the variable name is slightly different)
and I think it is grotesque.  It's usually better to let the programmer
choose her own names for variables.  I suggest not doing this, although
I don't feel very strongly about it.

Date: 20 Jan 87 13:15 PST
From: Gregor.pa@Xerox.COM

I like the new :around method-combination option.  I think this will
make it easier for people to deal with :around methods.  We might want
to think about changing the "sense" of this option, or changing the
default, so that aroundification happens by default.

I agree that once it's a yes/no option, it makes sense to have it turned on
by default.  The next logical step is to say that if you want to turn it
off, you should be operating at the meta-object level.  Do you ever feel
like you're going around in circles?  What got us to :around methods in the
first place was you guys' dislike of Flavors whoppers, which cannot be
turned off.  (Obviously if Flavors had meta-objects, whoppers could be
turned off at the meta-object level.)

I have two suggestions here.  Either one is okay with me:

(1) Make it a method-group keyword option.  Thus you say
((around (:around) :call-next-method t) ...other method groups...)

(2) Decide the existing mechanism of two nested calls to make-method-call
is concise enough.

I understand the motivation for allowing a predicate instead of the
templates.  I think that motivation should be presented explicitly since
without it, the predicate seems like uneeded complexity.

correctly that you invented the idea of putting the predicate here?)

I don't really like the fact that information is communicated to
make-method-call using special variables.  I thought having
make-method-call be a lexically bound function was much more elegant,
and much more in keeping with the lexically scoped way of doing things.

It's a difficult judgement call.  What convinced me was that if error
reporting is going to use the Common Lisp condition handling standard, that
inherently involves dynamic variables, so there is nothing to be gained by
making make-method-call not use dynamic variables.  I suggest leaving this
the way it is.

I don't really like method-combination-error and invalid-method-error.
They just add complexity to this part of the proposal to make up for the
fact that the error system has not been adopted yet.  There are many
parts of the object system which want to signal special kinds of errors,
we don't have special functions for all of them.

This is the first place where we have a hook for programmer-defined
functions, and those functions have to report errors in a standard way.
Perhaps there will be others in the meta-object protocol, but so far there
aren't any others.

Perhaps what we should
do is assume the error system is going to be accepted (seems likely),
and then talk about what kind of error is signalled by each part of the
object system.  This seems more reasonable than introducing a bunch of
error functions which will just have to be removed when the error
proposal is adopted, or worse yet supported as backwards compatibility
for life.

We've found that it's often a good idea to provide a function as an
abstraction, even when all that function does is signal a condition.
The name of the condition can be the same as the name of the function,
so that there aren't any extra names to document.  This is what I had
in mind here, rather than making a kludge to cope with not having a
standard condition system yet.

I suggest leaving this the way it is except for documenting the rationale
better.

I still don't like calling the default kind of method combination
standard.  I would prefer if we called it default, in fact, it might be
better to call it daemon-with-around or some other descriptive name.

I disagree.  I really liked Danny's suggestion of calling it standard.  As
you know, I think all the predefined objects that are used by default if
you don't make your own should be named standard-xxx (standard-class,
standard-method, etc.)  I suggest naming it either standard or
standard-method-combination.

What method combination types will we say are defined?  There is a
definite package problem here.  We should probably include some comment
on it in the spec.  A user can't very well go and do
define-method-combination of lisp:and.  If they do it "differently" they
could break the system or some other application.  I think the examples
should be re-worked to show users defining method-combinations whose
names are symbols which are not in the lisp package.

This is a hard problem.  It relates to modularity and to the difficulty of
legislating programming styles in standards.

It's true that redefining lisp:and differently will break other programs.
A good programming environment will detect this and won't let it go
unchallenged, but if lisp:and is predefined in some environments and not in
others, so that every portable program has to define it, that doesn't help.
It's really not a good idea for every program to redefine and method
combination for itself, with its own name -- that just leads to a Tower of
Babel.  On the other hand, not everyone seems to agree that there should be
a library of a dozen or so useful predefined method combination types.
One answer is for that library to be available, but not necessary to be