Jump to content
  • Advertisement
Sign in to follow this  
Kreative

Best language for solving diamond problem & is this a good idea for multiple inheritance?

This topic is 1027 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

This is my first time in these vast forums, and I've come today to ask you if you know of a programming language that has a good solution for the diamond problem unlike C++'s workarounds of virtual inheritance, using :: to specify which super-class to get the implementation from etc.

I also wanted to share my (probably naive and) basic solution for multiple occurrences from multiple super-classes of the same method named implementation in a class, which is to call both implementations in alphabetical order of the super-classes' names. I have a very strong feeling that there could be many problems linked to this form of behavior for classes, yet I fail to see them. I seek criticism on this solution, and if no faults apply to this behavior please do approve.

Kind Regards,
Kreative

Share this post


Link to post
Share on other sites
Advertisement

I suspect most people here will suggest trying composition instead of using inheritance at all. It's easier to get what you want, and you don't have to fight with the language.

QFE.

Most cases where people encounter the diamond problem, in my experience, are cases where composition was more likely to be the appropriate choice. Edited by Washu

Share this post


Link to post
Share on other sites
It sounds like you aim for a language-theoretic discussion. A gamedev forum is probably not the optimal place for that. You may also want to try a forum or mailing list about programming language theory.

Having said that, people here are likely to have a very different view on the problem here, which is what you may be after. Personally, I know you can do multiple inheritance, but I rarely need it. I know the diamond thingie exists, but I have yet to run into one, and I have been programming OOP for about 20 years. In my experience, you write class hierarchies specifically for a goal, and you don't randomly merge it with other class hierarchies ever. Obviously, ymmv, it highly depends in what kind of systems you normally work, probably. If I ever run into one, my first reaction would be to think real hard whether this form of multiple inheritance is really good, and if so, rename a variable or use a pointer to resolve the issue.

I have probably read the C++ solution at some point, but have forgotten all about it. This may be the whole story. From a language theoretic point of view, diamond thingies are highly interesting no doubt, but they are so rare in practice, that basically any solution will do where you can express explicitly how it should be solved, no matter how ugly (ie you want to have an escape if it happens, diamond thingies are ugly already, an ugly work-around doesn't make much difference).

Using alphabetical order, or any other fixed order that cannot be changed easily is probably evil. Your solution may run into trouble when a class gets renamed, in particular a class that is not under your control, but eg from some library.
I would expect in the general case that you need several solutions, maybe two classes need to share the data, but a 3rd class needs its own copy.

Share this post


Link to post
Share on other sites

A gamedev forum is probably not the optimal place for that.


I know what you mean, this website showed up in my google search of "programming forums," and I was hesitant to post this thread until I saw the sub-forum, general programming which stated in the description, programming NOT related to games, so I had a go. I tried coding forums but my registration, account activation or something is a bit buggy and I don't have permission to do anything. So this is where I decided to go for general programming discussion and the only reason I've ever done programming in my life is for game creation, so even this is personally related to game design.
 

 


most people here will suggest trying composition instead of using inheritance at all

 


cases where composition was more likely to be the appropriate choice.


I know composition is usually much easier, however I am killing myself over repetition in programming languages, which in my (probably naive) understanding is the primary purpose of any form of complexity in programming. You can express almost everything in programming in a very long form without using lists, classes, etc, but it will contain millions time more repetition and likely other problems.

Composition can probably eliminate the need for almost any form of inheritance, however using inheritance mostly makes code shorter and less repetitive, imagine an insanely rare case of a triple occurrence of the diamond problem with multiple inheritance, using composition would usually lead to you having to do things like instanceOfClassA.instanceOfClassB.instanceofClassC.instanceOfClassD for every function or variable you're going to use. Although I should expect this never to happen in my lifetime, repetition, how ever little, in my opinion, should always be eliminated.

Note:
I've decided that instead of putting, (probably naive) everywhere I make assumptions or state opinions, I'll just say I'm very naive in programming practice and theory, I hope people read this note so they won't assume that I think that I am right and that I state facts, where they know something I said is an extremely huge assumption or obviously false.

Kind Regards,
Kreative

Edited by Kreative

Share this post


Link to post
Share on other sites
Just slapping an instance of a class into some place as if it was a drop-in replacement for inheritance is not the same as doing composition correctly.

Share this post


Link to post
Share on other sites

I'm not really sure what language selection has to do with it. While I've only seen it as an occasional problem in C++, I've only seen it exist in C++ and Python.  

 

Wikipedia lists a few other languages beyond C++ and Python that support multiple inheritance, but none are really game related (Lisp, Curl, Dylan, Eiffel, Logtalk, Object REXX, Scala, OCaml, Perl, POP-11, and TCL).  So if you aren't using any of those languages, problem solved. Yay.

 

 

 

In C++ it isn't normally a problem. It is extremely rare to create a situation with a diamond, the normal inheritance case leaves you with two different grandparents. This normal case if you derive from multiple bases you need to specify which to use by implementing the behavior and doing it yourself, specifying which parent's parent to use. And since C++ doesn't have a built-in system that calls base::method() or super() method, there isn't a problem for a default base.  A diamond is only created if you explicitly specify virtual inheritance. The only way to have the problem is to intentionally create it, and it is only intentionally created when it is intentionally needed. So it isn't normally a problem here.

 

Python also potentially has the problem, but again, it isn't normally encountered in games.  The way it is handled is explicitly specified in the language design, it is handled by the order of inheritance. Python DOES support a super() functionality, but the handling is well defined by the ordering.  And like C++, if you need to specify which path to take that is different from the default, you can use that parent's function explicitly. You can use super().method() for automatic use, or you can specifically call base.method() to be clear about it.

Share this post


Link to post
Share on other sites

The diamond problem? The diamond of death? Every language with class inheritance has that issue. Really, it's just up to the programmer to catch what he's doing. And... I have never heard of anyone actually encountering said issue... unless he gets a diamond in his spaghetti soup object structure.

 

And... I wouldn't say avoid inheritance in general. It's actually really the only way you can get things done pretty efficiently, elegantly, and with less code. For 

Share this post


Link to post
Share on other sites

I know the diamond thingie exists, but I have yet to run into one, and I have been programming OOP for about 20 years. In my experience, you write class hierarchies specifically for a goal, and you don't randomly merge it with other class hierarchies ever.
This. I think C++ deals with it sufficiently by not dealing with it at all. It's something you practically never encounter (I can't name a single case that I've encountered, ever).

 

But you could give Java a try, it tackles the problem by only allowing single inheritance. No multiple inheritance, no diamond possible (though I haven't touched Java for about 10 years, and I was told that in the meanwhile they do allow a kind-of-multiple inheritance through the backdoor).

Share this post


Link to post
Share on other sites

I know composition is usually much easier, however I am killing myself over repetition in programming languages, which in my (probably naive) understanding is the primary purpose of any form of complexity in programming. You can express almost everything in programming in a very long form without using lists, classes, etc, but it will contain millions time more repetition and likely other problems.

Composition can probably eliminate the need for almost any form of inheritance, however using inheritance mostly makes code shorter and less repetitive, imagine an insanely rare case of a triple occurrence of the diamond problem with multiple inheritance, using composition would usually lead to you having to do things like instanceOfClassA.instanceOfClassB.instanceofClassC.instanceOfClassD for every function or variable you're going to use. Although I should expect this never to happen in my lifetime, repetition, how ever little, in my opinion, should always be eliminated.

Note:
I've decided that instead of putting, (probably naive) everywhere I make assumptions or state opinions, I'll just say I'm very naive in programming practice and theory, I hope people read this note so they won't assume that I think that I am right and that I state facts, where they know something I said is an extremely huge assumption or obviously false.

Kind Regards,
Kreative

 

 

You can avoid complexity and repetition in other ways without inheritance/member functions etc by using techniques found in the functional world, such as high order functions and the like. The more I play in the functional space the more I find myself move away from OO techniques in favour of these other techniques, I find them more concise, I use far less code and get more code reuse.

 

Now C++ has lambda and closures use can employ many of these techniques in that language as well although its lambda syntax is ugly as imho

 

I recommend you have a play with F# or one of the lisps (scala is popular way to ease you way in) or if you want to really turn your thinking on its head look at haskell, the most hardcore functional language there is. It has a purity and simplicity that is beautiful. You will start to encounter monads and other computational building blocks that ease coding and remove much of the noise in your code that does not actually describe the problem but just controls flow etc.

 

Even if you do not do much with this languages it they will give you mindsets that you find permeate throughout your code no matter the space you work in and give you a whole new bag of tricks and ways to solve problems no matter the language you work in. Functions and data merge and become pretty much the same thing :)

 

The following are a couple of validators from a roguelike I have been playing with in C# but using immutability and functional code. They hook validation monads into the Linq computational engine and if any of the validation fails the code short circuits and the rest does not execute, the result is either the item selected at the end or the error message describing the failure. Notice the lack of control flow or even if statements. All the functions are statics and extensions, no member functions at all, all the branching and control provided by my validation monad and hidden away by Linq.

        public static IValidation<Level> CanSpawnActor(
            this Level level, long actorId, Vector location)
        {
            return
                from isNew in level.IsNewActor(actorId)
                from targetTile in level.IsValidMove(location)
                select level;
        }

        public static IValidation<Level> CanMoveActor(
            this Level level, long actorId, Vector newLocation)
        {
            return
                from actorState in level.ActorStateExists(actorId)
                from actorTile in level.IsValidLocation(actorState.Location)
                from actor in actorTile.HasActor(actorId)
                from withinRange in actorState.IsWithinMoveRange(newLocation)
                from validMove in level.IsValidMove(newLocation)
                select level;
        }

I believe the diamond inheritance shape should be the last solution you look at :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!