| Thread overview | |||||
|---|---|---|---|---|---|
|
October 22, 2008 Multiple Dispatch in practice | ||||
|---|---|---|---|---|
| ||||
On the Lambda the Ultimate forum I have just found a nice article about Multiple Dispatch in Practice: http://homepages.mcs.vuw.ac.nz/~alex/files/MuscheviciPotaninTemperoNobleOOPSLA2008.pdf I have seen that this topic was also discussed here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=56018 This is normal D1 code that shows a manual implementation of double dispatch: import std.stdio: writefln; /// ... template IsInstance(Class) { static assert(is(Class == class), "IsInstance: Class must be a class"); bool IsInstance(TyObj)(TyObj obj) { return cast(Class)obj !is null; } } interface Vehicle { void collide(Vehicle v); } class Car : Vehicle { void collide(Vehicle v) { if (IsInstance!(Car)(v)) writefln("Car hits car"); else if (IsInstance!(Bike)(v)) writefln("Car hits bike"); else throw new Exception("missing case: should not happen"); } } class Bike : Vehicle { void collide(Vehicle v) { if (IsInstance!(Car)(v)) writefln("Bike hits car"); else if (IsInstance!(Bike)(v)) writefln("Bike hits bike"); else throw new Exception("missing case: should not happen"); } } void main() { Vehicle car = new Car(); Vehicle bike = new Bike(); car.collide(bike); // Car hits bike car.collide(car); // Car hits car bike.collide(car); // Bike hits car bike.collide(bike); // Bike hits bike } With built-in multiple (double) dispatch the two classes become something similar to this: class Car : Vehicle { void collide(Car c) { writefln("Car hits car"); } void collide(Bike b) { writefln("Car hits bike"); } } class Bike : Vehicle { void collide(Car c) { writefln("Bike hits car"); } void collide(Bike b) { writefln("Bike hits bike"); } } Bye, bearophile | ||||
October 23, 2008 Re: Multiple Dispatch in practice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | Tue, 21 Oct 2008 22:01:15 -0400,
bearophile wrote:
> This is normal D1 code that shows a manual implementation of double dispatch:
>
> import std.stdio: writefln;
>
> /// ...
> template IsInstance(Class) {
> static assert(is(Class == class), "IsInstance: Class must be a class");
>
> bool IsInstance(TyObj)(TyObj obj) {
> return cast(Class)obj !is null;
> }
> }
>
> interface Vehicle {
> void collide(Vehicle v);
> }
>
> class Car : Vehicle {
> void collide(Vehicle v) {
> if (IsInstance!(Car)(v))
> writefln("Car hits car");
> else if (IsInstance!(Bike)(v))
> writefln("Car hits bike");
> else
> throw new Exception("missing case: should not happen");
> }
> }
>
> class Bike : Vehicle {
> void collide(Vehicle v) {
> if (IsInstance!(Car)(v))
> writefln("Bike hits car");
> else if (IsInstance!(Bike)(v))
> writefln("Bike hits bike");
> else
> throw new Exception("missing case: should not happen");
> }
> }
>
> void main() {
> Vehicle car = new Car();
> Vehicle bike = new Bike();
>
> car.collide(bike); // Car hits bike
> car.collide(car); // Car hits car
> bike.collide(car); // Bike hits car
> bike.collide(bike); // Bike hits bike
> }
You overcomplicate.
import std.stdio;
void main() {
Vehicle car = new Car();
Vehicle bike = new Bike();
car.collide(bike); // Car hits bike
car.collide(car); // Car hits car
bike.collide(car); // Bike hits car
bike.collide(bike); // Bike hits bike
}
interface Vehicle {
void collide(Vehicle v);
void onCollision(Car c);
void onCollision(Bike b);
}
class Car : Vehicle {
override void collide(Vehicle v) {
v.onCollision(this);
}
override void onCollision(Car c) {
writefln("Car hits car");
}
override void onCollision(Bike b) {
writefln("Bike hits car");
}
}
class Bike : Vehicle {
override void collide(Vehicle v) {
v.onCollision(this);
}
override void onCollision(Car c) {
writefln("Car hits bike");
}
override void onCollision(Bike b) {
writefln("Bike hits bike");
}
}
| |||
October 23, 2008 Re: Multiple Dispatch in practice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | Sergey Gromov:
> You overcomplicate.
> ...
> interface Vehicle {
> void collide(Vehicle v);
> void onCollision(Car c);
> void onCollision(Bike b);
> }
You oversemplificate :-) You have had to modify the original interface. I'll not use your version of the code. Multiple dispatch allows you to not modify the original interface, keeping changes more localized. If Car manages 5 collisions, while Bike 7, and they share just 3 collisions, your interface and classes become quite hairy...
Bye,
bearophile
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply