I've just released version 0.07 (alpha) of Cmm, a source-code
translator that adds support for multimethods to C++. This version has
been built with g++ 2.95.2 and STLport 4.1b2. It's released under the
GPL.
You can get Cmm from: http://www.op59.net/cmm/readme.html
People might also be interested in `Frost', a completely different
system for adding multimethods to C++ that I've come across recently -
see: http://www.flewid.de/julian/ (no relation).
- Julian
Sent via Deja.com http://www.deja.com/
Before you buy.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
afunction( Polymorph<BaseClass> parameter1, Polymorph<AnotherBaseClass>
parameter2)
std::map[key] = Polymorph<BaseClass> item;
Walt Howard
Julian Smith <my-...@op59.net> writes:
> There's been talk on this newsgroup recently about possible additions
> to the C++ standard, so:
>
> I've just released version 0.07 (alpha) of Cmm, a source-code
> translator that adds support for multimethods to C++. This version has
> been built with g++ 2.95.2 and STLport 4.1b2. It's released under the
> GPL.
>
> You can get Cmm from: http://www.op59.net/cmm/readme.html
>
> People might also be interested in `Frost', a completely different
> system for adding multimethods to C++ that I've come across recently -
> see: http://www.flewid.de/julian/ (no relation).
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
I don't understand what you mean by this bit of code, and I'd be very
surprised if you could replace Cmm (or the Visitor patter, or Item 31
in Meyer's More Effective C++) by something so simple. Could you
explain?
- Julian
Sent via Deja.com http://www.deja.com/
Before you buy.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
I went back to my Meyers More Effective C++ book, section 31 and read
it again.
The Polymorph won't handle that situation.
However, that situation is broken. It's a good example, of broken
polymorphism and a way to work with it. I think it would be easier
just to fix it. To tell you the truth, I didn't study the last half of
the chapter. The time would be better spent on a semester of nuclear
physics I think :)
In a good, polymorphic hierarchy, a scout ship, a battle ship etc are
ALL spaceships and the code to determine a collision doesn't need to
know exactly which class is involved. The code only needs to be
written for spaceship. If a scout ship isn't a spaceship, it shouldn't
be in the IS-A hierarchy. Sure, each type of ship might specialize but
it has to support the essential spaceship methods and that's all the
collision function should be calculating with. The virtual functions
of each class will cause the differing results of a collision.
I would never write something like that, and if I were handed some
code like that to fix I would be bummed.
But, to return to the point, I stand corrected and you are right.
Julian Smith <my-...@op59.net> writes:
> In article <wk3dg7t...@wallyware.com>,
> Walt Howard <wa...@wallyware.com> wrote:
> > You don't need this really. The Polymorph template class I posted
> > earlier does this without any preprocessor AND enables you to extend
> > the analogy of virtual function parameters to virtual data of any
> > kind.
> >
> > afunction( Polymorph<BaseClass> parameter1,
> Polymorph<AnotherBaseClass>
> > parameter2)
> >
> > std::map[key] = Polymorph<BaseClass> item;
>
Did I write that?
The core power of the polymorph is you can use an actual variable,
where you used to only be able to use a reference or pointer.
This whole area is tricky. I know someone who has used the visitor
pattern's `pass a statically-typed reference to yourself to some else's
statically-typed method, and have them call your virtual method' trick
working for more than two objects. We discussed it as a way of
optimising Cmm's dispatch code, but unfortunately the vistor pattern,
unlike Cmm, doesn't mimic C++'s compile-time behaviour where dispatch
can be ambiguous. Actually, I'm secretly glad, because I wouldn't like
to write code that generates code that does multiple visitor-pattern
tricks...
>
> In a good, polymorphic hierarchy, a scout ship, a battle ship etc are
> ALL spaceships and the code to determine a collision doesn't need to
> know exactly which class is involved. The code only needs to be
> written for spaceship. If a scout ship isn't a spaceship, it shouldn't
> be in the IS-A hierarchy. Sure, each type of ship might specialize but
> it has to support the essential spaceship methods and that's all the
> collision function should be calculating with. The virtual functions
> of each class will cause the differing results of a collision.
I don't agree. A conventional single-dispatch virtual function only
allows you to test for overlap between a generic spaceship and a
specialised spaceship. The only non-multimethod-style way I can see to
make an overlap function for two spaceships is for each to provide a
generic `shape' object whose base interface contains enough information
to do overlap detection for any shapes.
For example, `shape' could be a bitmask, or a closed vector path. Using
a bitmask would be ok for small space-invader-style things, but
inefficient for large simple polygons, and the reverse would apply for
a vector path, so you could choose whichever fitted your spaceships
best.
But then what do you do if you want some spaceships to be small space-
invaders, and others to be large polygons? Without multimethods or
similar, you're stuck.
The problem isn't that Meyer's scout ship is not a spaceship; it's that
a language that only provides `IS-A' and single dynamic dispatch is not
easily capable of modelling things which depend on the dynamic types of
more than one object at the same time. You can't easily make overlap
detection be part of a spaceship class's base interface.
A more interesting example is that of event dispatching in a GUI. You
have a dynamically typed window object (text editor, browser window
etc), and a dynamically typed event (mouse click, keypress etc etc).
The code that should be called to respond to the event depends on both
of these dynamic types. You simply can't do this simply in most
languages, which is why message map / slot-signal systems are grafted
on. I'd like to see what things would be like if multimethods were
supported - you'd do things like (using Cmm's multimethod syntax):
// GUI header
struct Window {...};
struct Event {...};
struct EventMouseClick : Event {...};
struct EventKeypress : Event {...};
void HandleEvent( virtual Window&, virtual Event&);
// GUI implementation
void HandleEvent_( Window&, EventMouseClick&) {...}
void HandleEvent_( Window&, EventKeypress&) {...}
// My application
struct MyWindow : Window {...};
void HandleEvent_( MyWindow& w, EventMouseClick) {...}
Because there is no void HandleEvent_( MyWindow&, EventKeyPress&), a
keypress in a MyWindow would be handled by the generic GUI
implementation void HandleEvent_( Window&, EventKeypress&).
Another example is generating error messages in different languages.
Again, you have two dynamic types - the error type, and the language
type. Multimethods would be useful because you could always provide an
error function for each error and the abstract base language type
(which could output in English I guess), which would be called by
default if the code for the currently configured language wasn't
available.
>
> I would never write something like that, and if I were handed some
> code like that to fix I would be bummed.
>
> But, to return to the point, I stand corrected and you are right.
>
> Julian Smith <my-...@op59.net> writes:
> > > afunction( Polymorph<BaseClass> parameter1,
> > Polymorph<AnotherBaseClass>
> > > parameter2)
> > >
> > > std::map[key] = Polymorph<BaseClass> item;
> >
>
> Did I write that?
'fraid so!