Re: Multimethods idioms and library support
On Feb 22, 4:33 pm, Victor Bazarov <v.baza...@comcast.invalid> wrote:
On 2/22/2011 9:04 AM, itaj sherman wrote:
On Feb 22, 3:17 pm, Victor Bazarov<v.baza...@comcast.invalid> wrote:
On 2/22/2011 8:09 AM, itaj sherman wrote:
Is there any concensus idiom on how to code with multimethods?
How would you go about coding them today?
There's the multi-dispatch idiom: For each override type of the first
parameter. declare a different virtual function to dispatch the second
parameter.
http://en.wikipedia.org/wiki/Multiple_dispatch
But it requires that the definition of every polymorphic class of one
parameter #includes the definition of all polymorphic types of the
following parameter. This makes the code messy, and not scalable due
to circular dependencies between modules.
Not necessarily. If your arguments are references (as they should be),
you only need forward-declarations to declare those member functions.
In the translation unit, of course, you'll need the corresponding
headers included. But that's no mess, that's just a necessity.
What I was saying about this specific dynamic_cast dispatch idiom, is
that I don't think it's a very good one.
By "mess" I meant extra bookkeeping work on code management, that
would be unnecessary if there was a better library to support
multimethods instead this specific idiom.
I'm trying see if anyone knows such library, or a better idiom.
The problem with that is that one cannot use this multimethods idiom
in a core module with intentions for users of the module to inherit
his classes and define their overrides.
Why not? The core module provides a way for objects *defined in it* to
interact. Why can't you expand the core module model and provide more
interaction between yet unknown classes (that you define in your own
modules)? Do you see the idiom breaking down somehow?
What problem are you trying to solve? Let's try together. Show us
where you hit an obstacle, perhaps we can come up with a solution...
Very, well.
I won't get into descibing the real module I was working on that
triggered my problem, but I can describe a very short example to
demonstrate it.
For example:
An animal kingdom module defines base classes Carnivour and Prey.
And a multimethod:
void hunt( Carnivour const&, Prey& );
I want to enable users of my module to have their classes inherited
from Carnivour or Prey, and enable them to define override functions
for hunt special for their types.
A certain user then create his classes: Lion, Anaconda and Bear
derived from Carnivour, Giraffe and Gazelle derived from Prey.
He also wants to override the possible hunt implementation.
The following code demonstrates how I wished it could be written
(based on the proposition in "The Design and Evolution of C++ Bjarne
Stroustrup").
I'm looking for a library that will support such multimethods.
Basically replacing the hipothetic language syntax with some library
constrcuts. But enable the same general construction and dependency of
the module and user code.
The dynamic_cast dispatch idiom cannot do that (it's becoming too
lengthy, I'll demonstrate if further post).
//using some hipothetic multimethod syntax
//////my module "animal kingdom"
////animal_kingdom/carnivour.h
class Carnivour
{
};
////animal_kingdom/prey.h
class Prey
{
};
////animal_kingdom/hunt.h
//define a multimethod void hunt( Carnivour const&, Prey& )
#include "carnivour.h"
#include "prey.h"
void hunt( virtual Carnivour const& carnivour, virtual Prey& prey ) =
0;
//////From here on the user code
////lion.h
#include "carnivour.h"
class Lion: public Carnivour
{
};
////the same way files for:
class Anaconda: public Carnivour {};
class Bear: public Carnivour {};
class Giraffe: public Prey {};
class Gazelle: public Prey {};
////hunt_override_1.cpp
#include "lion.h"
#include "Gazelle.h"
void hunt( override Lion&, override Gazelle& )
{
//jumps on it and bite its neck
}
//and same for:
void hunt( override Lion&, override Girrafe& )
{
//bite its ass
}
void hunt( override Anaconda&, override Gazelle& )
{
//inject venom
}
//Anaconda can't kill girrafes so no override for that one
void hunt( override Bear&, override Prey& )
{
//because Bears catch everything in the same way lol.
}
//main.cpp
int main()
{
Carnivour& carnivour = Bear(...);
Prey& prey = Gazelle(...);
void const result( hunt( carnivour, prey ) );
}
itaj