Talk:Double dispatch
From Wikipedia, the free encyclopedia
[edit] Article needs a careful rewrite
I began to correct what appeared to be only minor errors, when I realized that this article basically needs a careful rewrite.
A few notes:
A compiler cannot statically compute the function pointer offset for a dynamically bound method.
The double dispatch pattern can be implemented in any language. It's meaningless to talk about languages that do or don't support double dispatch.
There is a runtime cost of double-dispatch, but it should not to be confused with the cost of dynamic method binding.
Basically, much of the article confuses two related, but distinct, concepts: dynamic method binding and the double dispatch pattern. In part, this confusion arises because the examples use a statically typed language, C++, where both issues are important. I would recommend using a dynamically typed language (e.g. Smalltalk or Python) to explain double dispatch. Since all method binding is dynamic in a dynamically typed language, there's no point of distiction, and the dynamic method binding won't obscure the double dispatch concept.
—The preceding unsigned comment was added by 164.223.72.6 (talk • contribs) 20:32, 5 July 2005 (UTC1)
I disagree with a statement above. It's certainly meaningful to talk about language support for double dispatch, or anything else. I can implement control and data structures, object-oriented programming and exception handling in assembly language. That doesn't mean assembly language has support for these things. This kind of ignorant statement slides toward the naive Turing equivalence argument: that any Turing complete language has the same support for doing everything that can be done in any other Turing complete language. That is a fallacy, because support has to do with expressiveness, not raw computability.
Multiple dispatch is a form of overloading. It's overloading based on a latent type, so it would not be wrong to call it dynamic overloading. C++ style overloading is based on manifest type only. That's the difference. Overloading would become multiple dispatch if the dynamic type of each argument were considered, whenever the argument is a reference to a base class.
The issues in this page are confused; it is asserted that overloading does one dispatch through a virtual table. That is false. Overloading has nothing to do with virtual tables. C++ supports overloading for non-member functions, and for static member functions. Virtual functions can be overloaded too, yes. What happens then is that the particular variant is first chosen based on the static argument list using ordinary overload resolution. Under overload resolution for object calls, the object is considered to be a hidden zeroth argument. Its manifest (static) type is used. If overload resolution comes up with a unique best candidate, then the function is called, and normal virtual dispatch takes place. By then, the parameters are no longer considered; they have been dealt with. Whatever overload gets called through the virtual table, it necessarily has that exact argument list. A virtual funtion overloads another only if the name and parameter signature match.
Another key difference between multiple dispatch and (C++) overloading is that C++ overloading has rules that can fail to come up with a unique candidate, thereby stopping the translation of the program. By contrast, in the Lisp object system, if there exist suitable primary methods that can satisfy a call, one will be chosen. Ambiguities are resolved using left to right base class precedence. If a D is derived from B1 and B2, it is "slightly more" a B1 than a B2. Only if no primary method can be found will the be an error: a run-time "method not found" condition.
In C++, it's possible to introduce a new overload function to a program which will make it invalid. That is to say, a program can contain some overloaded functions, and calls to them, which successfully resolve. It's possible to introduce a new function which ambiguates the call, so that the program can no longer compile.
—The preceding unsigned comment was added by 24.83.96.126 (talk • contribs) 18:52, 21 October 2005 (UTC1)
[edit] SpaceShip example
I found that the code as presented didn't execute as expected: I had to add the following methods -
class SpaceShip { public: virtual void CollideWith(Asteroid& inAsteroid) { inAsteroid.CollideWith(*this); } virtual void CollideWith(ExplodingAsteroid& inAsteroid) { inAsteroid.CollideWith(*this); } }; class GiantSpaceShip : public SpaceShip { virtual void CollideWith(Asteroid& inAsteroid) { inAsteroid.CollideWith(*this); } virtual void CollideWith(ExplodingAsteroid& inAsteroid) { inAsteroid.CollideWith(*this); } };
bob towers. —The preceding unsigned comment was added by 82.153.33.97 (talk • contribs) 01:15, 7 February 2007 (UTC1)
This example seems to be copy/pasted from Scott Meyers book. Is he aware of that? 15.227.137.70 20:30, 11 April 2007 (UTC)