If you like to have an example look at the collections hierarchy. That is a perfect example for that. These are full of "diamond problems". And what options do you have to solve it? Here my top approaches (worst first):
- code duplication. Don't need to comment that - delegation. Adds a lot of one line methods. Code is growing and is error prone - moving implementation up the hierarchy. This leads to something like ArrayedCollection>>add: newObject self shouldNotImplement - traits. Not easy to understand and adds complexity
I'm not sure which one is better of the last two. And I'm also not sure if collections are the only useful example for using traits. For me it is an language option I can use or not. Every approach has its drawbacks you have to think about. For me even inheritance can be seen that way.
This discussion raises some tensions. For me it is important to make a difference between "my opinion about traits" and "if traits should stay in the image". And I hope we don't discuss about banning traits from the image. To make traits a real option it should be removed but only if it is reloadable. Removing it without being able to reload it would be a big loss.
So, where's the problem? Even Stef agrees that to have it reloadable would be a good choice. I think it's because it has to be proven and be done.
Norbert
On Fri, 2008-05-16 at 01:52 -0700, Ryan Mitchley wrote:
I am genuinely curious to see a simple example that clearly demonstrates the advantages of traits.
It is my perception (or misperception) that traits are an attempt (perhaps unknowingly) to bring multiple inheritance into the language. As I see it, this confuses Y Is-A X (i.e. Y subclasses X) with Y Has-A-Part X (i.e. Y has a member variable / subpart / trait X)
I've seen this in GUI toolkits - e.g. someone has a Bitmap class and a ClickableArea class. They want to make a Button - i.e. something that has both Bitmap and ClickableArea traits. So they create Button by inheriting from both Bitmap and ClickableArea classes (usually C++). The better solution is to say that Button has both Bitmap and ClickableArea parts (i.e. member variables). This confusion becomes ridiculously clear if we attempt to create e.g. a Human class by inheriting from Eye, Leg, Arm etc. There is very likely much confusion between all of the members that get dragged in and try to compete with each other.
So, if I have a mistaken view of traits, I would in all honesty love to see an example that shows this to me clearly.
I have a strong view that software should be designed with a very high view of orthogonality. I will often reject non-orthogonal approaches in my own software without much thought, simply because I have been down that road before and seen the trouble that ensues. That's why I would suggest that traits should be rejected IFF they turn out to be a non-orthogonal design (i.e. their utility is duplicated by e.g. member variables). I am not yet convinced one way or the other.