digitalmars.D - Suggestion: Walter Bright, why not to implement multiple inheritance in D?
- Arlen Albert Keshabyan (60/60) Dec 01 2006 Recently, I've started the subject about multiple inheritance in D. I've...
- Justin C Calvarese (11/20) Dec 01 2006 This has been discussed to death in the past.
- Chris Nicholson-Sauls (32/108) Dec 01 2006 I'm not Walter, and I'm no expert in the implementation of languages, an...
- Gregor Richards (52/73) Dec 01 2006 Yeah, obviously. I mean, who the hell uses Java or C#?
- Gregor Richards (4/4) Dec 01 2006 Addendum:
- Kyle Furlong (2/106) Dec 02 2006 The Gregor (tm) strikes again!
- Burton Radons (79/94) Dec 02 2006 The solutions to getting around MI when it's necessary are by their very...
- Larry Evans (6/17) Dec 02 2006 [snip]
- Kyle Furlong (2/21) Dec 02 2006 God, Boost makes me want to stab my eyes out.
- Walter Bright (3/6) Dec 02 2006 I would suggest using instead D's ability to declare the members of a
- Larry Evans (17/26) Dec 10 2006 Good point.
- Walter Bright (2/6) Dec 12 2006 Could you provide a distilled explanation of what dynamic inheritance is...
- Larry Evans (70/77) Dec 21 2006 :* Distilled_Explanation:
- Burton Radons (33/52) Dec 02 2006 That's a good example. Here's another from Wikipedia:
- Larry Evans (10/29) Dec 04 2006 Well, I'm kinda agreeing with Walter. AFAICT, the example in
- Burton Radons (30/30) Dec 02 2006 As an aside to Walter, I stumbled on a solution to the multiple vtable
- Walter Bright (2/7) Dec 02 2006 That is a good idea.
- BCS (6/14) Dec 02 2006 That is how I think interfaces should work.
Recently, I've started the subject about multiple inheritance in D. I've got the answers. But those solutions are not enough suitable for my purposes. Then I thought, why not to implement the feature which is on demand by programmers in D? Multiple inheritance is needed indeed just only by seeing the attempts of programmers to emulate it in D. It means they need it. Multiple inheritance is really not that bad thing which is supposed to be got rid of. Just a linear multiple inheritance with possibility to get to the every level of its hierarchy is enough, I think. Moreover, I'll help to port many useful C++ code into D much easier than now. I know two approaches by now, but both are restrictive to feel the freedom of multiple inheritance. First approach is excellent, but does not allow you to get as deep as you want to the class hierarchy (only super's virtual methods are accessible explicitly): ////////////////////////////////// interface I { } class A(T) : T, I { } class B(T) : T, I { } class C(T) : T, I { } alias C!(B!(A(Object))) D; //////////////////////////////// Second approach is excellent too, but lacks template merging possibilities and pointing explicitly which interface function to implement (on name collisions): ////////////////////////////////////// interface A { } interface B { } interface C { } template A_() { } template B_() { } template C_() { } class D : A, B, C { mixin A_; mixin B_; mixin C_; } //////////////////////////////// Walter, is it a matter of principle not to implement multiple inheritance in D? If D is the language of practical usage then multiple inheritance must be considered to implement. What do you think?
Dec 01 2006
Arlen Albert Keshabyan wrote:Recently, I've started the subject about multiple inheritance in D. I've got the answers. But those solutions are not enough suitable for my purposes. Then I thought, why not to implement the feature which is on demand by programmers in D? Multiple inheritance is needed indeed just only by seeing the attempts of programmers to emulate it in D. It means they need it. Multiple inheritance is really not that bad thing which is supposed to be got rid of. Just a linear multiple inheritance with possibility to get to the every level of its hierarchy is enough, I think. Moreover, I'll help to port many useful C++ code into D much easier than now.This has been discussed to death in the past. Feel free to read up on the past arguments. Here's a couple threads to get you started (I'm sure more threads are out there)... 16 Aug 2001: http://www.digitalmars.com/d/archives/43.html 18 Mar 2004: http://www.digitalmars.com/d/archives/25807.html I think the bottom line is the multiple inheritance would added too much complexity for too little benefit. If the program has been designed in C++, it might need some re-design to bring it into D. -- jcc7
Dec 01 2006
Arlen Albert Keshabyan wrote:Recently, I've started the subject about multiple inheritance in D. I've got the answers. But those solutions are not enough suitable for my purposes. Then I thought, why not to implement the feature which is on demand by programmers in D? Multiple inheritance is needed indeed just only by seeing the attempts of programmers to emulate it in D. It means they need it. Multiple inheritance is really not that bad thing which is supposed to be got rid of. Just a linear multiple inheritance with possibility to get to the every level of its hierarchy is enough, I think. Moreover, I'll help to port many useful C++ code into D much easier than now. I know two approaches by now, but both are restrictive to feel the freedom of multiple inheritance. First approach is excellent, but does not allow you to get as deep as you want to the class hierarchy (only super's virtual methods are accessible explicitly): ////////////////////////////////// interface I { } class A(T) : T, I { } class B(T) : T, I { } class C(T) : T, I { } alias C!(B!(A(Object))) D; //////////////////////////////// Second approach is excellent too, but lacks template merging possibilities and pointing explicitly which interface function to implement (on name collisions): ////////////////////////////////////// interface A { } interface B { } interface C { } template A_() { } template B_() { } template C_() { } class D : A, B, C { mixin A_; mixin B_; mixin C_; } //////////////////////////////// Walter, is it a matter of principle not to implement multiple inheritance in D? If D is the language of practical usage then multiple inheritance must be considered to implement. What do you think?I'm not Walter, and I'm no expert in the implementation of languages, and I am in fact guilty of using multiple inheritance often enough... But I will say this much. I've been working on implementing my own BovisMOO language for a project, and within Bovis I've allowed for multiple inheritance, despite its predecessor (LambdaMOO) being strictly single inheritance. Which caused a very simple lookup which looked roughly (pseudo-code) like this: To now look like this: All off the top of my head, but that's more-or-less how it goes. Yes, it does work, but it sure became a lot uglier and a lot less efficient... and this is just for a weak-typed little scripting language with no concepts of classes or interfaces! I can only imagine what horrors it might lead to in a full systems programming language with rich OOP features. I'd say the main reason it isn't there, is to prevent Walter from having migraines. And I don't consider that a completely unmerited excuse. :) -- Chris Nicholson-Sauls
Dec 01 2006
Arlen Albert Keshabyan wrote:Recently, I've started the subject about multiple inheritance in D. I've got the answers. But those solutions are not enough suitable for my purposes. Then I thought, why not to implement the feature which is on demand by programmers in D? Multiple inheritance is needed indeed just only by seeing the attempts of programmers to emulate it in D. It means they need it. Multiple inheritance is really not that bad thing which is supposed to be got rid of. Just a linear multiple inheritance with possibility to get to the every level of its hierarchy is enough, I think. Moreover, I'll help to port many useful C++ code into D much easier than now. I know two approaches by now, but both are restrictive to feel the freedom of multiple inheritance. First approach is excellent, but does not allow you to get as deep as you want to the class hierarchy (only super's virtual methods are accessible explicitly): Walter, is it a matter of principle not to implement multiple inheritance in D?No.If D is the language of practical usage then multiple inheritance must be considered to implement.What do you think?Multiple inheritance is a terrible idea on at least two levels: 1) In class trees with functions or (worse yet) variables with the same name at different levels, it's confusing to the programmer to figure out what name maps to what. 2) The way OO is implemented in 99% of compiled programming languages, multiple inheritance is impossible. Let me explain: // this is the structure representing an object struct Object { struct ClassInfo *classInfo; struct RandomGarbage whateverTheLanguageNeeds; // variables go here } // this is the structure representing a class struct ClassInfo { struct ClassInfo *parent; // <many other things> void **vtable; } vtable is an array of function pointers, like so for example class A.vtable = 0 -> foo() 1 -> foo(int) now imagine we have a class derived from the one described above. To make it usable as the base class, it has a vtable like this class A(B).vtable = 0 -> foo() 1 -> foo(int) 2 -> bar() 3 -> bar(float) Hey presto! If you pass in an object with this vtable, it will work for both, because calling the function foo just involves calling vtable[0]! Now, imagine the multiple-inheritance scenario. We have these two classes: class A.vtable = 0 -> foo() 1 -> foo(int) class B.vtable = 0 -> baf() 1 -> baf(Object) Now we'd like to make a class C derived from both A and B: class C(A, B).vtable = 0 -> ??? 1 -> ??? 2 -> (C's own functions) Now can you see the problem? We can't simply dereference vtable[0] or vtable[1] to get the proper function, because there are two different classes, each with their own vtable[0] and vtable[1]. There are solutions to this (obviously, since C++ works), but they're usually arcane and always inefficient. - Gregor Richards
Dec 01 2006
Addendum: Incidentally, it's usually considered bad form to use multiple inheritance in C++. - Gregor Richards
Dec 01 2006
Gregor Richards wrote:Arlen Albert Keshabyan wrote:The Gregor (tm) strikes again!Recently, I've started the subject about multiple inheritance in D. I've got the answers. But those solutions are not enough suitable for my purposes. Then I thought, why not to implement the feature which is on demand by programmers in D? Multiple inheritance is needed indeed just only by seeing the attempts of programmers to emulate it in D. It means they need it. Multiple inheritance is really not that bad thing which is supposed to be got rid of. Just a linear multiple inheritance with possibility to get to the every level of its hierarchy is enough, I think. Moreover, I'll help to port many useful C++ code into D much easier than now. I know two approaches by now, but both are restrictive to feel the freedom of multiple inheritance. First approach is excellent, but does not allow you to get as deep as you want to the class hierarchy (only super's virtual methods are accessible explicitly): Walter, is it a matter of principle not to implement multiple inheritance in D?No.If D is the language of practical usage then multiple inheritance must be considered to implement.What do you think?Multiple inheritance is a terrible idea on at least two levels: 1) In class trees with functions or (worse yet) variables with the same name at different levels, it's confusing to the programmer to figure out what name maps to what. 2) The way OO is implemented in 99% of compiled programming languages, multiple inheritance is impossible. Let me explain: // this is the structure representing an object struct Object { struct ClassInfo *classInfo; struct RandomGarbage whateverTheLanguageNeeds; // variables go here } // this is the structure representing a class struct ClassInfo { struct ClassInfo *parent; // <many other things> void **vtable; } vtable is an array of function pointers, like so for example class A.vtable = 0 -> foo() 1 -> foo(int) now imagine we have a class derived from the one described above. To make it usable as the base class, it has a vtable like this class A(B).vtable = 0 -> foo() 1 -> foo(int) 2 -> bar() 3 -> bar(float) Hey presto! If you pass in an object with this vtable, it will work for both, because calling the function foo just involves calling vtable[0]! Now, imagine the multiple-inheritance scenario. We have these two classes: class A.vtable = 0 -> foo() 1 -> foo(int) class B.vtable = 0 -> baf() 1 -> baf(Object) Now we'd like to make a class C derived from both A and B: class C(A, B).vtable = 0 -> ??? 1 -> ??? 2 -> (C's own functions) Now can you see the problem? We can't simply dereference vtable[0] or vtable[1] to get the proper function, because there are two different classes, each with their own vtable[0] and vtable[1]. There are solutions to this (obviously, since C++ works), but they're usually arcane and always inefficient. - Gregor Richards
Dec 02 2006
Gregor Richards wrote:Now we'd like to make a class C derived from both A and B: class C(A, B).vtable = 0 -> ??? 1 -> ??? 2 -> (C's own functions) Now can you see the problem? We can't simply dereference vtable[0] or vtable[1] to get the proper function, because there are two different classes, each with their own vtable[0] and vtable[1]. There are solutions to this (obviously, since C++ works), but they're usually arcane and always inefficient.The solutions to getting around MI when it's necessary are by their very exclusion from base language features always arcane, often inefficient, and almost always incomplete. The language-standard D solution is mixins, which I am certain are a bad idea even if they worked better than they do. 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 exception, where MI is not just being used to alias an object to multiple types (and would therefore be better handled with a field)? Because if that statement is true, then the biggest problem in multiple inheritance can be ignored because all non-abusive usages of it would be resolvable into a clean array, no more difficult than single inheritance, except that methods that exist in more than one separate hierarchies should disappear without manual overloading. What I mean is: class A { void foo (int); } class B { void foo (float); } class C : A, B { void bar () { foo (16); } // Invalid because foo exists in both A and B. If we overloaded them, it would be like selecting between two functions from different modules. So for language consistency's sake, foo is not visible here. } class D : A, B { void foo (int x) { A.foo (x); } void foo (float x) { B.foo (x); } void bar () { foo (16); } // But this is okay. } Or better yet: class E : A, B { alias A.foo; alias B.foo; } The key is in not disallowing something just because it's difficult, but because it's wrong, always wrong, negative index on an array wrong. I'm inclined to think my assertion must be correct, but I can't quite discern the law ruling it. One way in which it is ALWAYS correct is with patterns like this: interface I { void foo (); } class A : I { void foo () { ... } } class B : I { void foo () { ... } } class C : A, B { } This is because A and B's implementation of foo must be different, so the user is literally asking two objects to exist in one point at the same time, which is not logical. The inheritor cannot confidently select between them with any consistency (which is the fallback MI languages use if they are intelligent enough to notice the problem at all), because he cannot consistently know what either of those methods do (if the method's changed over time, or is written by another maintainer). Since this is an unsolvable ambiguity, it must be wrong to do this. Gregor Richards wrote:Addendum: Incidentally, it's usually considered bad form to use multiple inheritance in C++.Yeah, but C++ programmers are programming in C++. The hell do they know about good language practices? ;-)
Dec 02 2006
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?
Dec 02 2006
Larry Evans wrote:On 12/02/2006 09:27 AM, Burton Radons wrote: [snip]God, Boost makes me want to stab my eyes out.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?
Dec 02 2006
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.
Dec 02 2006
On 12/02/2006 09:33 PM, Walter Bright wrote:Larry Evans wrote: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 :)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.
Dec 10 2006
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?
Dec 12 2006
On 12/12/2006 09:49 PM, Walter Bright wrote:Larry Evans wrote::* 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 ;) .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?
Dec 21 2006
Larry Evans wrote:On 12/02/2006 09:27 AM, Burton Radons wrote: [snip]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? :-)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?
Dec 02 2006
On 12/02/2006 10:11 PM, Burton Radons wrote:Larry Evans wrote:[snip]On 12/02/2006 09:27 AM, Burton Radons wrote: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++.
Dec 04 2006
As an aside to Walter, I stumbled on a solution to the multiple vtable problem a couple years ago. Instead of putting the vtable in the object, you put it in the reference, like with a delegate. Then if an object is posing as a base type, you just select an appropriate vtable and offset the pointer. That way you don't need to worry about trying to fit vtables into base types, although you still need to put offsets into the vtable for mutual base types in the (A; B : A; C : A; D : B, C) case for field pointers. Didn't say it was a panacea. It's no good for D, though. Too bad because (even without MI) it would easily allow other functionality. There's no reason then to keep value and reference types separate, for example, and a mostly-equivalent vtable can be selected based upon contextual needs. I had an example for why you'd want to do that around but I can't remember it now. Ah, here's one: say you take a reference of a middle value in an array. If someone tries to delete this reference, you can either delete the whole array (bad), sigsegv (bad), ignore it because it's not a pointer to the beginning of the block (bad because if it were a reference to the first array element it would still be nonsensical to delete it but it would work), ignore it because it's a reference to an array element (better, and possible with the scheme here), or remove it from the array (which is probably best but depends upon storing the length with the array data, which might be more correct overall but has too many bad points to counter its few good ones. But if arrays WERE implemented like that, this scheme would allow that to happen efficiently). It'd remove the need for boxing, too, since you could just convert a value into a reference, cast it to void&, then try to cast it back into a value type. It's a little faster on dispatch, of course; one less pointer to follow. Likely a little slower when all's considered. Oh well, stuff for my language, if I ever get around to that.
Dec 02 2006
Burton Radons wrote:As an aside to Walter, I stumbled on a solution to the multiple vtable problem a couple years ago. Instead of putting the vtable in the object, you put it in the reference, like with a delegate. Then if an object is posing as a base type, you just select an appropriate vtable and offset the pointer.That is a good idea.
Dec 02 2006
Walter Bright wrote:Burton Radons wrote:That is how I think interfaces should work. It has a whole host of cool implications: interfaces from structs, functions, on-the-fly literals or wherever delegates can be done. Make a .tupleof for interfaces, and a template could even build one. (I'll get off of my soap box now) <g>As an aside to Walter, I stumbled on a solution to the multiple vtable problem a couple years ago. Instead of putting the vtable in the object, you put it in the reference, like with a delegate. Then if an object is posing as a base type, you just select an appropriate vtable and offset the pointer.That is a good idea.
Dec 02 2006