December 02, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | On 12/02/2006 09:27 AM, Burton Radons wrote: [snip] > I don't have a perfect solution to the problem; there is none because it's asking two objects to exist in one space and we need to resolve that. But given that multiple inheritance is sometimes necessary, waving it off as "too complex" or "bad form" is impractical; like any type of suppression, that only leads to cracking and nasty leaks (mixins). > > I have an idea. Let's try making this assertion: no type will have in its inheritance tree another type multiple times without being an abuse of multiple inheritance. Given this statement, can anyone find an [snip] > Yeah, but C++ programmers are programming in C++. The hell do they know about good language practices? ;-) How would the D equivalent to mpl::inherit_linearly<, inherit<,>, > (see http://www.boost.org/libs/mpl/doc/refmanual/inherit-linearly.html) work without using the MI class, inherit? |
December 03, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Evans | Larry Evans wrote:
> On 12/02/2006 09:27 AM, Burton Radons wrote:
> [snip]
>> I don't have a perfect solution to the problem; there is none because it's asking two objects to exist in one space and we need to resolve that. But given that multiple inheritance is sometimes necessary, waving it off as "too complex" or "bad form" is impractical; like any type of suppression, that only leads to cracking and nasty leaks (mixins).
>>
>> I have an idea. Let's try making this assertion: no type will have in its inheritance tree another type multiple times without being an abuse of multiple inheritance. Given this statement, can anyone find an
> [snip]
>> Yeah, but C++ programmers are programming in C++. The hell do they know about good language practices? ;-)
>
> How would the D equivalent to mpl::inherit_linearly<, inherit<,>, >
> (see http://www.boost.org/libs/mpl/doc/refmanual/inherit-linearly.html)
> work without using the MI class, inherit?
God, Boost makes me want to stab my eyes out.
|
December 03, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Evans | Larry Evans wrote:
> How would the D equivalent to mpl::inherit_linearly<, inherit<,>, >
> (see http://www.boost.org/libs/mpl/doc/refmanual/inherit-linearly.html)
> work without using the MI class, inherit?
I would suggest using instead D's ability to declare the members of a struct using tuples.
|
December 03, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Evans | Larry Evans wrote:
> On 12/02/2006 09:27 AM, Burton Radons wrote:
> [snip]
>> I don't have a perfect solution to the problem; there is none because it's asking two objects to exist in one space and we need to resolve that. But given that multiple inheritance is sometimes necessary, waving it off as "too complex" or "bad form" is impractical; like any type of suppression, that only leads to cracking and nasty leaks (mixins).
>>
>> I have an idea. Let's try making this assertion: no type will have in its inheritance tree another type multiple times without being an abuse of multiple inheritance. Given this statement, can anyone find an
> [snip]
>> Yeah, but C++ programmers are programming in C++. The hell do they know about good language practices? ;-)
>
> How would the D equivalent to mpl::inherit_linearly<, inherit<,>, >
> (see http://www.boost.org/libs/mpl/doc/refmanual/inherit-linearly.html)
> work without using the MI class, inherit?
That's a good example. Here's another from Wikipedia:
Animal
Mammal : Animal
Winged : Animal
Bat : Mammal, Winged
Contrived but not unreasonable, but I think the problem I gave applies even if they don't override any of the parent methods, just as a pure maintainer problem of the subclasses depending upon the implementation of the parent class.
We could restrict diamonds to interfaces, like it's done now, but that feels like a hack and doesn't actually solve the problem - in fact, it makes the problem necessary. Damn. I retract my challenge.
Perhaps we're trying to shoehorn two types of inheritance into one tree. Something that's Winged is an Animal, but it's not a /complete/ animal; it's not going to have any opinion on its feeding habits. So we could use:
Animal
Mammal : Animal
Winged : abstract Animal
Bat : Mammal, Winged
And allow the diamond because Winged can't override anything from Animal. This is bad because Animal might have stuff Winged has an opinion on, but more discrete selections of inheritance (which are a good idea anyway) allows us to defeat the diamond when we need to:
Reproduction
Movement
Animal : Reproduction, Movement
Mammal : abstract Animal, Reproduction
Winged : abstract Animal, Movement
Bat : Mammal, Winged
In this case Mammal and Winged are exclusive, so the tree works properly.
I'd analyse your example more but I'm unfamiliar with Boost. Can you factor the problem so that it can be expressed in terms of animals? :-)
|
December 04, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Burton Radons | On 12/02/2006 10:11 PM, Burton Radons wrote: > Larry Evans wrote: > >> On 12/02/2006 09:27 AM, Burton Radons wrote: [snip] > And allow the diamond because Winged can't override anything from Animal. This is bad because Animal might have stuff Winged has an opinion on, but more discrete selections of inheritance (which are a good idea anyway) allows us to defeat the diamond when we need to: > > Reproduction > Movement > Animal : Reproduction, Movement > Mammal : abstract Animal, Reproduction > Winged : abstract Animal, Movement > Bat : Mammal, Winged > > In this case Mammal and Winged are exclusive, so the tree works properly. > > I'd analyse your example more but I'm unfamiliar with Boost. Can you factor the problem so that it can be expressed in terms of animals? :-) Well, I'm kinda agreeing with Walter. AFAICT, the example in boost which used inherit was used to create a tuple, and since there's now a better way (as Walter pointed-out), I'm reluctant to try. However, if I did, there would be a problem with the abstract Animal (or virtual Animal in c++ case). I don't see a way that can be done with c++ metaprogramming since all the args to boost::mpl::inherit have to be types, and, AFAICT, there's no type, virtual X, for any type X, in c++. |
December 10, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 12/02/2006 09:33 PM, Walter Bright wrote: > Larry Evans wrote: > >> How would the D equivalent to mpl::inherit_linearly<, inherit<,>, > >> (see http://www.boost.org/libs/mpl/doc/refmanual/inherit-linearly.html) >> work without using the MI class, inherit? > > > I would suggest using instead D's ability to declare the members of a struct using tuples. Good point. Now, I've another use of c++ MI, and I'm wondering how to do the equivalent in D. This use involves "dynamic inheritance" which is somewhat like the 12.7 Delegation in Stroustrup's _Design and Evolution of c++_. The code is used here: http://preview.tinyurl.com/wwsee The test code is in the corresponding libs/grammar_pipeline/test directory. One application of such dynamic inheritance was discussed here: http://article.gmane.org/gmane.comp.lib.boost.devel/99421 Of course, a more concrete application was in the aforementioned tinurl reference. So...how would this be done in D? Since the above application involved calculating grammar lookahead sets, and since you're interested in emulating spirit in D, this might provide some further motivation for finding a D equivalent :) |
December 13, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Larry Evans | Larry Evans wrote:
> So...how would this be done in D? Since the above application involved calculating grammar lookahead sets, and since you're interested in
> emulating spirit in D, this might provide some further motivation
> for finding a D equivalent :)
Could you provide a distilled explanation of what dynamic inheritance is?
|
December 21, 2006 Re: Suggestion: Walter Bright, why not to implement multiple inheritance in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 12/12/2006 09:49 PM, Walter Bright wrote: > Larry Evans wrote: > >> So...how would this be done in D? Since the above application >> involved calculating grammar lookahead sets, and since you're >> interested in >> emulating spirit in D, this might provide some further motivation >> for finding a D equivalent :) > > > Could you provide a distilled explanation of what dynamic inheritance is? :* Distilled_Explanation: Dynamic Inheritance (a.k.a. DI, as coded here: in http://tinyurl.com/yd7ean ) is really nothing more than the "infrastructure" for implementing "Dynamic Dual Heirarchies" as described on p. 5 of: http://www.objectmentor.com/resources/articles/dih.pdf which says: A dual heirarchy is like a ladder. The two inheritance heirarchies are the supports of the ladder, and in the INTELLIGENT CHILDREN pattern above, the 'has' relationships in the peers are the rungs of the ladder. An "abstract" picture of such a dual heirarchy is in figure 3 on p. 4. The left side of figure 3 is closer to DI than the right side. This is because the 'has' relationship is stored in the base class ( DI's dyn_inherit::inherit<,,>::super_type::my_ref, corresponding to figure 3's right-pointing solid arrow from B1 to B2). Thus, DI's inherit<,,> corresponds to figure 3's B1 and DI's inherit's DynSupertype template parameter corresponds to figure 3's B2. A more "concrete" picture is figure 2, where lhs of figure 3's B1 corresponds to figure 2's Observer, and lhs of figure 3's B2 corresponds to figure 2's Subject. In contrast to the Observer pattern which figure 2 describes, DI just has one pointer (as opposed to a set of pointers) from B2 (Subject) to B1 (Observers). This single pointer is stored in the dyn_inherit::base::my_subtype member of the DynSupertype of inherit (note the REQUIREMENTS: comment after DynSupertype specifying that it's derived from dyn_inherit::base). :* Preliminary_Conclusion Well, Walter, after I complete the :* Distilled_Explanation below, I realized there's probably no need for Proxy<> supertype of dyn_inherit::inherit, Instead this class could be made a field and the "relevant" function calls forwarded to the Proxy<>::get_ref() as done with the current implementation (e.g. as done by the eff::exp_tree::top::begin method here: http://tinyurl.com/yht62d ). However, that still leaves the dyn_inherit::base and DeltaType supertypes of dyn_inherit::inherit. So..., how would dyn_inherit::inherit be coded in D? ;* Name_and_Location_Rationale: Some of the names (for example DynSuperType and DeltaType for the 1st and 2nd inherit template arguments) may seem mysterious. The following explains how these names were selected. :** DynSuperType_Rationale: The reason for the DynSuperType (and it's inclusion in the Proxy<DynSuperType> supertype of inherit) is that type inherit supertype is "supposed" to correspond to the *p supertype of C in: class C : *p { ... }; from section 12.7, "Delegation", of Stroustrup's _Design & Evolution of C++_. The reason for the "supposed" qualifier above is that there's no automatic forwarding to *p as described in section 12.7. Since D has delegates, I thought maybe D could do this forwarding ( I confess, I've not written a single D program yet ). However, after reading: http://www.digitalmars.com/d/type.html#delegates I guess not, since delegates point to single functions instead of to classes :( . Would Mixin's be any help?. Well, http://www.digitalmars.com/d/mixin.html seems to say that a select set of declarations are *copied* from one context into another; however, what I want needed is delegation to each of the selected functions in the source context (i.e. the SynSuperType). Hence, I guess mixins wouldn't help either :( :** DeltaType_Rationale: The Delta comes from p. 2 of _Mixin-based Inheritance_ by Braca and Cook, which is available here: http://citeseer.ist.psu.edu/bracha90mixinbased.html . This Mixin part of the title tempts me to rethink whether D's mixin's can be some help, but, as mentioned above, I've not yet written a D program. I guess I should start ;) . |
Copyright © 1999-2021 by the D Language Foundation