[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Method Combination Proposal
- To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
- Subject: Re: Method Combination Proposal
- From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
- Date: Mon, 12 Jan 87 18:45 EST
- In-reply-to: <870108-232001-2402@Xerox>
Here are answers reflecting what I put into the document.
Date: 8 Jan 87 23:19 PST
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
If I was going to do those programming environment facilities,
I would try to do them by calling the method-combination function
and seeing what happens, rather than by adding a new syntax to be
used in the define-method-combination specifically to convey that
information. This is similar to the suggestion that the best way
to find out what methods are actually called is to call the
method-combination function and analyze the Lisp form it returns,
rather than adding a new syntax for it to return a list of methods.
I don't understand how this helps in finding unacceptable methods (with
bad method qualifiers). There can be any number of reasons (e.g.
shadowing with no call-next-method) why the result of a method
combination does not include some applicable methods. So the result
cannot be what is checked. It must then be some use of the selection of
methods that is used. This is not specified (or only implicitly) by the
template language (and by FIND-METHODS).
I straightened this out, I think (as much as I could without depending on
the condition system that has been proposed but not yet adopted). There
is a function, INVALID-METHOD-ERROR, which is called with the offending
method object as an argument, along with a string error message. The
programming environment can make this function do what it needs.
Looking back over the old discussion, the motivation
for the find-methods scheme was stated to be simplicity...
Yes, and I haired it up (sorry). But, I think the language for
FIND-METHODS is an independent issue from whether FIND-METHODS should be
used for specifying subsets of methods or only the template language.
The real issue I believe is whether FIND-METHODS can only be used in a
define-method-combination body (in which case probably the template
language is as good as having the form) or whether there can be
sub-functions that use it; clearly they cannot have the template
language. I prefer having subfunctions have the same capabiities as
forms in the main body.
I agree with the last sentence and I tried to make that the case as much
as possible in the latest version. It's not quite perfect but I think
it's adequate.
(define-method-combination mine ()
((methods (*)))
(grovel-my-method-combination #'make-method-call methods))
I found this very clever. However, I prefer to have the auxiliary
information in the metaobjects for the reasons you give.
This was so clever that I flushed it. Consulting notes and the rationale
section, we had already decided that we shouldn't do it this way and that
the extra information should be passed as special variables, not lexically.
So I changed it to work that way.
With respect to the method-selection process, I was embarrased to hear
an argument I always use thrown back at me
"this would be done in Lisp instead of a special embedded language")
However, doesn't this put all the error checking in Lisp, even for the
simple cases. I was proposing a simple error checking template language
with :qualifier-set. Or, perhaps I just missed the dual purpose of the
method-group specifiers, to select AND error check the set of applicable
methods.
The explanation and motivation should be much better and clearer now.
Are you saying that in place of the qualifier patterns one
could put the name of a predicate, in cases where the simple
pattern match language wasn't strong enough? That seems like a
good idea.
If we go with method-group specifiers, that is what I meant. The
predicate gets as an argument the list of all methods not yet selected
in the generic-function, and returns a subset.
I put this in, except I made the predicate get applied separately to each
method (actually to the qualifier list of the method), since I thought that
would be easier for the user and it's no less general. Also it shouldn't
be called a predicate if the value isn't true/false.
If I had to rank my objections, my strongest one is
against the lambda list.
I'd like to understand why.
Four reasons:
1) It hairs up the syntax of both define-method-combination and
defgeneric-options
This is weak. I don't see any significant complexity increase.
2) With no good simple example of its use, its utility is much in doubt
in my mind
This is strong.
3) In thinking about defining the arguments to the methods in the
meta-object protocol (e.g. compute-effective-method) I don't want to
have extra arguments sometimes.
It's just a list, not a variable number of arguments. (We're using the
word "arguments" to mean two different things. One is the arguments
given to the compute-effective-method generic function; the other is the
syntax of the :method-combination option to defgeneric-options, which
includes a "name" possibly followed by "arguments."). I think I wrote
this more clearly in the latest document; let me know how you like it.
4) Without this argument list, there is no need for a simple form of
DEFINE-METHOD-COMBINATION since the one form is simple enough. LEAN
proposal.
This is not true; I hope I've made things clear enough in the latest version
of the document that it's now obvious why it's not true.
In spite of #2, I left the lambda-list in, because of the need to pass
in the generic-function. We can discuss that more if it's a problem.
If the method combination arguments are constants for the generic
function, then a specialized generic function with such state is
sufficient.
I don't think a special magic way to put information into slots of the
generic-function and another special magic way to get it out again can
be considered less hairy syntax than a lambda-list. Programmers are
already familiar with lambda-lists.
It does imply though that some mechanism must be found for
the user to get access to the generic-function in the body of
define-method-combination. You said you had one you liked in Flavors --
what is it.
I didn't say that. We have one I -dislike-, which is that a variable with
a magic name in a magic package is bound to the generic-function.
Do we want to hair up defgeneric-options to allow extra state to be
specified? For example, one option of defgeneric-options could be
(:slots slot-name-1 slot-value1 ...)
I find this preferable since it extends a much more general facility to
the user.
I find this definitely excessive. It's using an H-bomb to kill a fly, and
also is syntactically poor because not all of the :method-combination
information would be in one place in the defgeneric-options.
In addition, I think the body of the method combination
should have access to the generic function in question. It
can't get it from the methods since methods can be on more than
one generic function.
I don't think that has been agreed to. It seems to be simpler
to allow sharing of method-functions, but not sharing of
method-objects.
After some more thought on this issue, I can't find a good case against
it. The form of argument against should be that one wants to change
some part of a method (say its function) and have this effect seen in
two generic functions. I cannot think of a plausible scenario.
I agree with you here, but...
Does this solve the access to the generic-function for
method-combination? Only if in the place where the generic function is
required there is a guarantee that a method is available. Is that
always possible?
...I wasn't so sure that getting the generic-function from the methods
was a good idea after all, because I can see cases where a method isn't
easily available, and because we might change our mind for some reason
about the data structure having a reference from a method to its
generic-function, so it didn't seem wise to depend on it. Instead I
just made the generic-function be passed as an argument, which seems
simplest all around except that you have to put in a declare ignore if
you don't use it, to be strict Common Lisp.
PROCLAIM-IDENTITY-WITH-ONE-ARGUMENT. I don't see that
this is an appropriate mechanism for dealing with this
optimization. It may just be the name which is upsetting me, I
am not sure yet.
The other way to deal with this is to make it a keyword
argument to make-method-call, which defaults to (eq operator
'progn). I would be happy with that; in fact I think it's what I
proposed originally, but when we discussed this in Menlo Park, the
change to PROCLAIM-IDENTITY-WITH-ONE-ARGUMENT was made (I forget
who proposed it and what the arguments were). Note that the simple
form of DEFINE-METHOD-COMBINATION would need this keyword argument
too.
The objections to the keyword were
1) it was an extra keyword
Better an extra keyword than an extra function, surely.
2) this information was something that was useful in more than this
context. Other method-combination types and other program constructing
programs can use the same information. Can we push this problem into the
COMPILER group for CommonLisp, and assume that they will propose
something like this? It seems inappropriate for the object standard.
I decided that it was a mistake to associate this with the compiler, and
that this was really highly specific to method-combination, so I took
out the extra function and put the extra keyword back in. I am now
completely convinced that it's wrong to do this with a function. If
people want to argue that it shouldn't be done at all, we can talk about
that. I put some motivational explanation into the document.
To my way of thinking, the syntax of DEFINE-METHOD-COMBINATION
is similar to the syntax of DEFMACRO and DEFSETF. By the way,
Flavors' DEFINE-METHOD-COMBINATION doesn't allow doc-strings.
Should we leave this out and allow this to be something beat back in by
the committee if necessary (Gives them a chance to piss on something).
I think it's better to be consistent. There are more useful places for
them to piss.