C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

multimethods - possible implementation

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Dylan Nicholson
Guest





PostPosted: Wed Mar 03, 2004 11:49 am    Post subject: multimethods - possible implementation Reply with quote



I was reading through some of the proposals for adding multimethods to
C++, including implementation details that talked a lot about RTTI
etc. etc., and O(N) call times depending on the number of multimethods
defined.
But surely there is a simple O(1) method that doesn't use RTTI at all,
providing that you can modify the vtable of a class on the fly (which
of course a compiler can do).

So for instance if an initial class definition is:

struct object
{
virtual ~object() { }
};

It contains a vtable with just the one entry.

Suppose the compiler then encounters the following function
declaration:

void interact(virtual object*, virtual object*);

It could then add a further function to the vtable, something like:

virtual __interact(object* obj) { interact(this, obj); }

(Of course for many compilers, it may be possible to point the vtable
entry directly to the standalone 'interact' function).

It then comes across the following:

struct square : object
{
int x;
int y;
int width;
};
struct circle : object
{
int x;
int y;
int radius;
};

void interact(virtual square* sqr, virtual circle* crc);

At this point, it needs to add a new entry to object's vtable like so:

virtual __interact1(circle* crc) { interact(this, crc); }

Then override this in square:

virtual __interact1(circle* crc) { interact(this, crc); }

And override circle's __interact entry:

virtual __interact(object* obj) { obj->__interact1(this); }

It might then encounter:

struct triangle : object
{
/* whatever */
};

void interact(virtual triangle* crc, virtual circle* tri);

This would only require overriding __interact in triangle's vtable:

virtual __interact1(circle* crc) { interact(this, crc); }

Now when an actual call to

interact(obj1, obj2)

is encountered in the code, this is translated as:

obj1->__interact(obj2);

So that if obj1 is a square, it will call

obj2->__interact1(obj1)

Which is obj2 is a circle, will call

void interact(virtual square* sqr, virtual circle* crc);

Likewise, if obj1 is a triangle, it will call

void interact(virtual triangle* tri, virtual circle* crc);

as expected. In any other circumstance, it would call the original
interact(object*, object*) function (which I suppose could be
undefined, thus generate a 'pure virtual function call' exception or
some such).

I haven't thought it much through for more than 2 virtual parameters,
but it would seem to follow a similar (if more complex) pattern.

I take it this isn't under serious consideration for inclusion in the
standard at this point, but is there much interest in it?

Dylan

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Julian Smith
Guest





PostPosted: Wed Mar 03, 2004 8:28 pm    Post subject: Re: multimethods - possible implementation Reply with quote



On 3 Mar 2004 06:49:55 -0500
[email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson) wrote:

Quote:
I was reading through some of the proposals for adding multimethods to
C++, including implementation details that talked a lot about RTTI
etc. etc., and O(N) call times depending on the number of multimethods
defined.
But surely there is a simple O(1) method that doesn't use RTTI at all,
providing that you can modify the vtable of a class on the fly (which
of course a compiler can do).

One practical problem is that, if there are more than one compilation units,
your idea requires changes to vtables and adding new virtual functions to
classes, at link time. This is certainly possible, but I suspect that making
life even more difficult for implementors wouldn't go down particularly well.

The other problem is more subtle. If I understand your suggestion properly,
it's basically getting the compiler to create double-dispatch code
automatically. But double dispatch has slightly different semantics from
C++'s overload-resolution (which is extended to dynamic types in the
multimethods extension proposal), because double dispatch dispatches on the
dynamic types of the parameters in order, where as C++'s overload resolution
treats all parameters equally.

Double dispatch has the advantage that it doesn't give `ambiguous dispatch'
errors, but it's arguably better to mimic C++'s existing static dispatch
semantics.

The proposal (http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1529.html)
talks about a different way of getting constant time dispatch. This works by
defining small integers to uniquely identify classes, and using them to index
into a dispatch array. Ultimately it's doing much the same thing as your
idea, just putting the dispatch information in a different place - tying
(multi-dimensional) vtables to multimethod functions instead of classes. It
suffers from the same problem in that it requires work at link time, but it's
actually possible to do things even later, at runtime, which makes it pretty
easy to implement.


Quote:

So for instance if an initial class definition is:

struct object
{
virtual ~object() { }
};

It contains a vtable with just the one entry.

Suppose the compiler then encounters the following function
declaration:

void interact(virtual object*, virtual object*);

It could then add a further function to the vtable, something like:

virtual __interact(object* obj) { interact(this, obj); }

(Of course for many compilers, it may be possible to point the vtable
entry directly to the standalone 'interact' function).

It then comes across the following:

[...]

Quote:
I haven't thought it much through for more than 2 virtual parameters,
but it would seem to follow a similar (if more complex) pattern.

I think double dispatch can be extended to more two parameters, but I've
never tried it.

Quote:

I take it this isn't under serious consideration for inclusion in the
standard at this point, but is there much interest in it?

Actually, I'm not particularly hopeful about getting multimethods into C++ at
all - there doesn't seem to be a particularly large amount of interest in the
C++ community, and most of the effort in the committee seems to be focused on
much simpler proposals and improving support for generic programming.

Quote:

Dylan

- Julian

--
http://www.op59.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Wed Mar 03, 2004 8:50 pm    Post subject: Re: multimethods - possible implementation Reply with quote



Dylan Nicholson wrote:
Quote:
I was reading through some of the proposals for adding multimethods to
C++, including implementation details that talked a lot about RTTI
etc. etc., and O(N) call times depending on the number of multimethods
defined.
But surely there is a simple O(1) method that doesn't use RTTI at all,
providing that you can modify the vtable of a class on the fly (which
of course a compiler can do).
snip


Your method doesn't seem to allow separate compilation - the compiler
needs to know about all derived classes of the second polymorphic
class type in a multimethod when generating vtables for derived
classes of the first.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dylan Nicholson
Guest





PostPosted: Thu Mar 04, 2004 2:10 pm    Post subject: Re: multimethods - possible implementation Reply with quote

Ben Hutchings <do-not-spam-benh (AT) bwsint (DOT) com> wrote

Quote:
Dylan Nicholson wrote:
I was reading through some of the proposals for adding multimethods to
C++, including implementation details that talked a lot about RTTI
etc. etc., and O(N) call times depending on the number of multimethods
defined.
But surely there is a simple O(1) method that doesn't use RTTI at all,
providing that you can modify the vtable of a class on the fly (which
of course a compiler can do).
snip

Your method doesn't seem to allow separate compilation - the compiler
needs to know about all derived classes of the second polymorphic
class type in a multimethod when generating vtables for derived
classes of the first.

Well, no, it would essentially have to build the final vtable
structure at link-time, and indeed ideally support it dynamically at
runtime, when loading shared libraries etc. I'm not pretending that
my suggestion is at all simple to implement, but at least it doesn't
suffer from the limitations of requiring RTTI.

Dylan

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dylan Nicholson
Guest





PostPosted: Thu Mar 04, 2004 2:11 pm    Post subject: Re: multimethods - possible implementation Reply with quote

Julian Smith <jules (AT) REMOVETHIS (DOT) op59.net> wrote

Quote:
On 3 Mar 2004 06:49:55 -0500
[email]wizofaus (AT) hotmail (DOT) com[/email] (Dylan Nicholson) wrote:

The other problem is more subtle. If I understand your suggestion properly,
it's basically getting the compiler to create double-dispatch code
automatically. But double dispatch has slightly different semantics from
C++'s overload-resolution (which is extended to dynamic types in the
multimethods extension proposal), because double dispatch dispatches on the
dynamic types of the parameters in order, where as C++'s overload resolution
treats all parameters equally.

I thought about this, I'm pretty sure that you could have both (e.g.):


void interact(virtual square* sqr, virtual circle* crc); //[1]

and

void interact(virtual circle* crc, virtual square* sqr); //[2]

This would mean that object's vtable has

__interact1(virtual circle* crc);
&
__interact3(virtual square* sqr);

Then square would override with:

__interact1(virtual square* sqr) { interact(this, sqr); } // call [1]

& circle would override with:

__interact3(virtual square* crc) { interact(this, crc); } // call [2]


Dylan

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Lorenzo Bettini
Guest





PostPosted: Fri Mar 05, 2004 10:28 am    Post subject: Re: multimethods - possible implementation Reply with quote

Hi

I developed doublecpp:

Doublecpp is a preprocessor for C++ that handles a new linguistic
construct for defining branches of a multi-method. The "right" branch
of such a method will be selected dynamically at run-time according to
the actual type of the object on which the method is invoked and to the
actual type of the first argument: double dispatch.

http://www.lorenzobettini.it/software/doublecpp/index.html

Doublecpp is free software; you are free to use, share and modify it
under the terms of the GNU General Public License (see COPYING).

The double dispatch is performed in *constant* time O(1), since it uses
dynamic binding twice (with a technique similar to the Visitor pattern).

Lorenzo



--
+-----------------------------------------------------+
Quote:
Lorenzo Bettini ICQ# lbetto, 16080134 |
PhD in Computer Science |
Dip. Sistemi e Informatica, Univ. di Firenze |
Tel +39 055 4796741, Fax +39 055 4796730 |
Florence - Italy (GNU/Linux User # 158233) |
Home Page : http://www.lorenzobettini.it |
http://music.dsi.unifi.it XKlaim language |
http://www.lorenzobettini.it/purple Cover Band |
http://www.gnu.org/software/src-highlite |
http://www.gnu.org/software/gengetopt |
http://www.lorenzobettini.it/software/gengen |
+-----------------------------------------------------+


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Fri Mar 05, 2004 10:32 am    Post subject: Re: multimethods - possible implementation Reply with quote

Dylan Nicholson wrote:
Quote:
Ben Hutchings <do-not-spam-benh (AT) bwsint (DOT) com> wrote in message
news:<slrnc4c8tj.okv.do-not-spam-benh (AT) shadbolt (DOT) i.decadentplace.org.uk>...
Dylan Nicholson wrote:
I was reading through some of the proposals for adding multimethods to
C++, including implementation details that talked a lot about RTTI
etc. etc., and O(N) call times depending on the number of multimethods
defined.
But surely there is a simple O(1) method that doesn't use RTTI at all,
providing that you can modify the vtable of a class on the fly (which
of course a compiler can do).
snip

Your method doesn't seem to allow separate compilation - the compiler
needs to know about all derived classes of the second polymorphic
class type in a multimethod when generating vtables for derived
classes of the first.

Well, no, it would essentially have to build the final vtable
structure at link-time, and indeed ideally support it dynamically at
runtime, when loading shared libraries etc.

It's worse than that - the dynamic linker would have to modify
vtable pointers in existing objects and virtual function calls
in the code as the vtables expanded. This is simply not going
to work in the presence of dynamic linking.

Quote:
I'm not pretending that my suggestion is at all simple to implement,
but at least it doesn't suffer from the limitations of requiring
RTTI.

I can see that it could be faster where it is applicable, but not
necessarily by that much. The speed of modern processors depends on
prediction of changes of control flow. The targets of virtual
function calls are often predicted wrongly and so are relatively slow
on average. The time taken to search a list of candidates (if
implemented by well-tuned code and not just an add-on written in C++)
and then make one indirect function call may be comparable to the cost
of the two virtual function calls.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.