![]() |
Multimethods idioms and library support
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. I had to use them for a some medium size hirarchy and this idiom became quite a bother. Not to mention that users coult not add their types becuase this idiom is circular dependant. I'm more interested in some library that would support this in a more generic way. I suppose any such library would need some compiler specific code for each compiler that it supports, but the API should be the same. BTW, Stroustrup in "The Design and Evolution of C++ Bjarne Stroustrup"/ 13.8 comsiders adding multimethods as a c++ language favorable. Although less important than many other features. And there are some proposals for it. However, I don't know there's currently any point in the future when it's predicted to be added. And a library solutions seems good itaj |
Re: Multimethods idioms and library support
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. >[..] V -- I do not respond to top-posted replies, please don't ask |
Re: Multimethods idioms and library support
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. > Agreed. But another big problem is also that you need many different virtual functions declarations each belongs to a certain polymorphic class of the next parameter. In the wikipedia example the names of the functions contain the class name, or you can add a dummy parameter using the type. But they must be different virtual functions declared. This is also what I meant by circular dependency, not just the #include. 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. itaj |
Re: Multimethods idioms and library support
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. >> > > Agreed. > But another big problem is also that you need many different virtual > functions declarations each belongs to a certain polymorphic class of > the next parameter. In the wikipedia example the names of the > functions contain the class name, or you can add a dummy parameter > using the type. But they must be different virtual functions declared. > This is also what I meant by circular dependency, not just the > #include. Uh... Yes. If an object of classA has to interact with objects of classB, classC and classD, all those classes will need virtual functions to interact with an object of classA. And if they need to interact with each other, they *need to know* about each other. And if you need to override those behaviors, you're going to have to provide some way for those objects to make the distinction between objects with which they need to interact. If that all is a "well, duh" moment for you, don't blame the language or the model, change them. > 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... V -- I do not respond to top-posted replies, please don't ask |
Re: Multimethods idioms and library support
On 2/22/2011 itaj sherman wrote:
> > 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. On 22 Feb., Victor Bazarov wrote: > 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? One of the problems is that you would have to add overloaded versions for each of your derived class in the base class interface. This may not be possible for libraries unless it is a header-only library. Regards, Stuart |
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 |
Re: Multimethods idioms and library support
On Feb 22, 5:40 pm, itaj sherman <itajsher...@gmail.com> wrote:
> On Feb 22, 4:33 pm, Victor Bazarov <v.baza...@comcast.invalid> wrote: > > > 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 dynamic_cast dispatch idiom cannot do that (it's becoming too > lengthy, I'll demonstrate if further post). > Well, I was wrong about "cannot do that". It is possible for this user. But it requires listing all dynamic_cast options for derived class. And the user still has to list them all in one place. On the other hand if someone later wants to add carnivour and prey classes he must have access to the implementations of other classes. I'll work on a good example for that. In any case I think it's much more bookkeeping than could be with some library support. Especially if it were 3 or more virtual parameters. However, I am mainly interested in how people usually code such cases, without any reference to my opinion about this idiom. So whichever way you use (or would use) in such cases, I'll take it as your answer to my question (this idiom or anything else). itaj |
Re: Multimethods idioms and library support
On 22 Feb., itaj sherman wrote:
[snip] > 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. [snip] The following should scale okay. #include <iostream> class CarnivourDispatch; class Prey { public: virtual void dispatchMe (CarnivourDispatch*) = 0; }; class Carnivour { public: virtual void hunt (Prey& prey) = 0; }; class Giraffe; class Gazelle; class CarnivourDispatch : public Carnivour { public: virtual void hunt (Prey& prey) { prey.dispatchMe (this); } virtual void _hunt (Gazelle&) = 0; virtual void _hunt (Giraffe&) = 0; }; class Lion: public CarnivourDispatch { protected: virtual void _hunt (Gazelle& Gazelle) { std::cout << "Lion jumps on gazelle and bites its neck."; } virtual void _hunt (Giraffe&) { std::cout << "Lion bites giraffe's ass"; } }; class Giraffe : public Prey { public: void dispatchMe (CarnivourDispatch* Hunter) { Hunter->_hunt (*this); } }; class Gazelle : public Prey { public: void dispatchMe (CarnivourDispatch* Hunter) { Hunter->_hunt (*this); } }; //main.cpp int main() { Carnivour* carnivour = new Lion; Prey* prey1 = new Gazelle; Prey* prey2 = new Giraffe; carnivour->hunt (*prey1); carnivour->hunt (*prey2); } Probably the dispatchMe-methods in Prey derived class should be added by a template, but I tried to keep it simple. Regards, Stuart |
Re: Multimethods idioms and library support
On Feb 22, 6:15 pm, Stuart Redmann <DerTop...@web.de> wrote:
> On 22 Feb., itaj sherman wrote: > > The following should scale okay. [snip code] You replace a dynamic_cast if-else-if list with a virtual function Prey::dispatchMe. This save the detailing on 1 parameter. I'm not sure it would be so helpful for 3 or more virtual parameters. Also the more internal animal_kingdom module contains Prey which has to know (forward-dec) the name of CarnivourDispatch which in turn has to know all polymorphic types under Prey. As it is, it breaks the encapsulation of the module, becuase user must make it somehow aware of his different derivations. I think that would be especially more problematic if there was another user-code adding more derivations, but that would want to use some of these derivations too. > Probably the dispatchMe-methods in Prey derived class should be added > by a template, but I tried to keep it simple. Yeah, ultimately everything should work conviniently for override implementation using some template functions, and also if any of the base classes (Carnivour or Prey) was actualy a template class. I don't think we stepped on anything for which that would cause difference. I'm sorry what I say here is not 100% formally clear. It's more like a brainstorm to evaluate idioms for multimethods. itaj |
Re: Multimethods idioms and library support
On Feb 22, 3:09*pm, itaj sherman <itajsher...@gmail.com> wrote:
> > BTW, Stroustrup in "The Design and Evolution of C++ Bjarne Stroustrup"/ > 13.8 comsiders adding multimethods as a c++ language favorable. > Although less important than many other features. And there are some > proposals for it. However, I don't know there's currently any point in > the future when it's predicted to be added. And a library solutions > seems good > ....Stroustrup in "The Design and Evolution of C++ Bjarne Stroustrup" paragraph 13.8, considers multimethods as a c++ language feature, a favorable addition. But less important... itaj |
| All times are GMT. The time now is 08:54 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.