[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Method Combination



    Date: 27 Jan 87 17:39:46
    From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET

    I agree with the fact than one can define ones own
    compute-effective-method. The issue has to do with modularity.
    Compute-effective-method has to find the list of all the method
    that can be called, find the method combination method, call it to
    come up with the code for the effective method.  We need to keep
    those operations as independent as possible.  If we supply the
    information as an argument to the method combinator, the user
    writing a method combination method does not have to worry about
    how the information was obtained.

I agree that finding the list of all the methods that can be called,
finding the way to combine methods, and coming up with the code for the
combination ought to be kept separate.  The following describes my view
of the meta-object protocol, and how these are kept separate.

The meta-object protocol for building the code for generic functions
consists of two parts.  The top level is

(compute-discriminator-code generic-function)

which has as its responsibility building the code that implements the
effect of the described four step protocol for calling a method.  Its
usual implementation caches all the possibly different effective methods
for the generic-function, and it produces code to decide which of these
effective methods to call for any set of arguments.  It is this code
that is run when the generic-function is called.  

The only information compute-discriminator-code can use must be
contained in the generic-function object.  THERE IS NO OTHER PLACE TO
STORE INFORMATION.

As a standard part of the protocol for compute-discriminator-code (which
can be overwritten by a specialized method), compute-discriminator-code
computes the set of applicable-methods for distinguishable sets of
arguments, and for that set calls:

(compute-effective-method generic-function combination-type
applicable-methods)
 
The combination-type is taken from the generic-function to allow
discrimination on an individual (the combination type) to select a
specialized method.  Other paramaterized information could have been
passed in as arguments, but since that information is not being used for
discrimination, it might as well be left in the generic function.


    Different implementations of compute-effective-method will be
    able to call the same method combinator even if they use different
    ways to come up with the method combination method.  It seems more
    modular and more general than extracting the information in the
    method.
If you want a subfunction that combines method-lists in the same way for
differently named method-combination types (say because the lists are
computed in different ways), then by all means define a subfunction.
That was the reason we wanted make-method-call to be callable any place
the generic-function object was accessible.

    Date: Wed, 28 Jan 87 00:05 EST
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    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.

I would rather do it the other way -- to make it easier to read the
document and to allow the need for a short form to emerge rather than
have it around by default.  Only one form should appear in the document,
and prhaps we should have a footnote saying that we might consider a
short form if necessary.


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

I think I have answered Patrick above.  If I have misunderstood the
thrust of the argument, please explain further.
    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?

I agree with this in principle, and would want to see the argument in
any particular case.


    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've answered for the lack of need for the lambda-list above. The
lambda-list cannot just be (). In your examples, it was at least
(generic-function) or (generic-function order). This is not even the
complete lambda-list of compute-effective-method (it doesn't include
combination-type and applicable-methods).

    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.
Most slightly shorter forms are used if they are available.  But I
wouldn't cry a lot if this were put back.

    I'm opposed to using optional arguments instead of keyword
    arguments, because it makes extensibility much more awkward.
This is a case in which allowing for extensions seems to be the
paramount issue.  Is it really musch easier to start with optionals and
then add keywords for extensions than to have all keywords.  Not having
programmed with them very much, I can't speak from experience.  I would
be happy to back off on this.
    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 think it will be less confusing for users to think of
:call-next-method as a special kind of operator.  We seem to have no
real disagreement here.  An argument for using the :call-next-method
instead of 'call-next-method (no colon) is to avoid people believing
that there is a function by that name, as there is for progn and and.

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

Can you say more about why you think it is grotesque. I find it easy to
spot and read. 

       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.

I think this is the simplest way to get access to the generic-function,
and if the programmer wants to use a name of her own, then she can
rebind it.  

Question:  How does make-method-call get access to the generic function.
I believed that it could assume access to that name in the lexical
scope.  Or perhaps generic-function should be a dynamic variable, to
allow access for an error function.

        (From Gregor) 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.

    (From Moon) 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.)
Because around methods are still somewhat contentious (e.g. with
Fahlman) that I think :around should be explicit in the
define-method-combination code, and it should have to be turned on.
Standard method combination supports it without having to say something.

        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.

    I agree.  Danny, could you write a paragraph about this?  (Am I
    remembering correctly that you invented the idea of putting the
    predicate here?)

Yes I will. Yes I did.

    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 could go either way with this.  If we have to document two kinds of
errors anyway, I guess it is as well to document functions.

       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.

I still like "standard" since it is only used in a context that makes it
clear what it is the standard for. 

    One answer is for that library to be available, but not
    necessary to be preloaded in all implementations.  Then the
    portable programmer can load it if it is not already loaded, but
    doesn't have to reinvent it. 

    I suggest that the document should mention this issue but that
    the name of and method combination in the example should still be
    and.

I agree with both of these points.  I think talking about standard
libraries here would be a good way of getting the point in the large,
without committing us to solve a problem.


My conclusion is that we should only have one define-method-combination
form in the document.  The one still contentious issue between Moon's
and my ideas on this subject is the lambda-list.  I hope this message
sheds more light on that issue.   We should continue to try to reach
some consensus.

danny