Topic: Will Support for RTTI in C++ Provide Multi-Methods?


Author: davisonj@bnr.ca (John M Davison)
Date: 21 Jul 1993 22:41:10 GMT
Raw View
       Now that the C++ standard meeting on March 7-12, 1993 has given C++ the
"dynamic_cast" operator, the "typeid" operator, the "Bad_cast" throw argument
type, the "Type_info" class, and the <Type_info.h> header file [1], the
question that I would ask is this: what does the future look like for
polymorphism that isn't restricted to member function invocation?  In
particular, I am curious about

    1. multi-methods (as in CLOS)
    2. other polymorphic non-member functions (i.e. single-argument
       multi-methods)

        To clarify #1, consider an inheritance DAG

                  +---+
                  | A |
                  +---+
                    |
                    |
                   /_\
                    |
                    |
                  +---+
                  | B |
                  +---+
                    |
                    |
                   /_\
                    |
                    |
                  +---+
                  | C |
                  +---+

and the function prototypes
    foo(A *arg1, A *arg2);
    foo(A *arg1, B *arg2);
    foo(A *arg1, C *arg2);
    foo(A *arg1);
    foo(B *arg1);
    foo(C *arg1);

        Currently, calling foo(A *arg1, A *arg2) where *arg2 is of type C will
still result in foo(A *arg1, A *arg2) being invoked and not foo(A *arg1, C
*arg2), since there is no notion of a "virtual" non-member function.

        What would be very nice, and what would really round out the
polymorphism in C++, would be if there were some way to make non-member
functions virtual, so that calling foo(A *arg1, A *arg2) where *arg2 is of type
C would actually result in foo(A *arg1, C *arg2) being called.

        For single-argment functions, the syntax would appear to be natural:

    virtual foo(A *arg1);
    foo(B *arg1); // may be called in place of foo(A *arg1)
    foo(C *arg1); // may be called in place of foo(A *arg1)

but when more than one argument is a polymorphic type, function declarations
like
    virtual foo(A *arg1, A *arg2);  // both arguments are handled "virtually"
    foo(A *arg1, B *arg2);
    foo(B *arg1, A *arg2);

would not work, since if both *arg1 and *arg2 are of type B, there is an
ambiguity.

        One could make multi-methods polymorphic on a per-argument basis, e.g.

    foo(virtual A *arg1, A *arg2); // argument 1 is handled "virtually"
    foo(B *arg1, A *arg2);         // may be called in place of foo(virtual A
                                   //  *arg1, A *arg2)
    foo(virtual A *arg1, B *arg2); // different "virtual" function altogether
    foo(A *arg1, virtual B *arg2); // another different "virtual" function

but again, the issue of ambiguity still arises if two arguments are made
virtual:

    foo(virtual A *arg1, virtual A *arg2); // neither argument binds at
                                           //  compile time
    foo(B *arg1, A *arg2); // if *arg1 and *arg2 are B's, would this be called?
    foo(A *arg1, B *arg2); // ...or this?

        Certainly the rules for "looking up" multi-methods would have to be
clearly spelled out -- there doesn't seem to be an obvious way to naturally
express them in the language, and the question of whether there would be only
one lookup scheme per process or per compilation unit would also arise.

        Surely someone has looked into this; does it look like multi-methods
will be included in standard C++?




[1] Lajoie, Josee.  Standard C++ Update: The New Language Extensions.
    _C++_Report_, Volume 5, Number 6, July-August 1993, pp. 47-52.
--
John Davison, davisonj@ecn.purdue.edu <---- send followups to THIS ADDRESS!!!!!
(Otherwise your mail will bounce!)  If you work at NT/BNR, please COCOS to
"John Davison".  The information contained in this article isn't necessarily
representative of Northern Telecom or BNR.