[squeak-dev] Re: Comments on traits usage [[Pharo-project] Fwd: traits :)]

Andreas Raab andreas.raab at gmx.de
Wed Jan 6 15:57:22 UTC 2010


David T. Lewis wrote:
> Comments on the topic of "what are traits good for?" from Nathanael,
> forwarded from Pharo list. This is in response to the question raised
> on this list a while back.

Interesting. Thanks for sharing! (and hi Nathanael!)

>>> Could someone please come up with ONE example where MI (traits in particular) solve an *actual* problem and not just some academic BS?
>> I have encountered a bunch of cases in my every-day work at Google where single inheritance was not good enough to write the functionality that we needed without (a) code duplication and/or (b) boilerplate for object delegation (plus the associated complexity/slow-down/etc.). This was getting so annoying that I went through the hassle of implementing a template-based traits mechanism in C++ that we have been using quite regularly.

C++, ouch. Yes, my comment wasn't aimed at C++ (or Java for that 
matter). In all statically typed languages that I'm aware of you really 
can't get around MI for the single reason of type compliance,  i.e., 
unless you can change a superclass' static type (which is impossible in 
many situations), the only option is to use MI in order to achieve type 
compliance.

>> For example, we have been designing and implementing a very complex framework for efficient handling of massive entity/relation graphs (billions of nodes). Since we needed this framework to be general across multiple aspects, we simply couldn't come up with a good way of doing this without some sort of MI, and traits proved to be extremely useful. So, based on my experience, I certainly have seen plenty of real-world applications where traits can make a tremendous difference!!

All right, I should've phrased that more carefully :-)

Yes, there *are* situations in which MI can solve a real, practical 
problem. I've had them. In my experience such situations center around 
the desire to modify existing (or future) frameworks without having to 
modify the base classes. The issue of static types is a classic in this 
regard, the above ("being general across multiple aspects") sounds very 
much like it as well but the idea is also applicable for example in 
"highly polymorphic" situations that affect few classes in a large 
hierarchy. I.e., instead of adding a hundred methods to a base class 
with the potential for conflicts one can use MI to cut down on the 
exposure of the base classes on the interface in question.

On the other hand, I'll say that whenever I had the ability to compare 
the alternatives, I've found that single inheritance and delegation 
result in solutions that are far simpler and easier to understand than 
multiple inheritance. The reason for this is obvious - it's the same 
reason that we have objects to begin with. It's usually the "other" 
constraints that make the single inheritance solution not viable, be 
that language weaknesses (can't modify superclasses), management 
constraints (changing the base class requires retesting of all of the 
dependent libraries, are you kidding me???) or performance implications 
(additional indirection(s) inherent in delegation).

>> That said, I can absolutely see that an overuse of traits can also add a lot of additional complexity. But in my opinion, this is not specific to traits and much more applies to almost any concept when it is overused. Consider for example single inheritance. If someone needs a class with 50 methods and decide to split this into a 10-level deep class hierarchy (just in case that somebody might want to reuse a part of it later), this will annoy a lot of other people and make things unnecessary complex. Similarly, if somebody splits a method with a 20 line algorithm into 10 helper methods with hard-to-understand names and consisting of only 2 lines each, this will probably make things much harder to understand (although having small methods is generally a good thing).

No argument here :-)

>> So, despite the fact that the concepts of single inheritance and (helper-)methods can be overused, I'm sure that neither of us would argue that they are bad/useless in the first place. And this is the same for any of the other nice programming concepts that come to mind, like meta-programming and closures (as much as I love closures for parametrization, overuse of functional elements can make code really hard to understand as well...)

No argument here either.

>> From my point of view, the same applies to traits: If traits are used in cases where they actually bring a benefit, i.e., they factor together a set of methods that conceptually and logically belong together and actually facilitate code reuse, they have been very useful to me.

Fair enough. I think I'm reacting a bit allergic to all of these 
academic examples that are praised as being oh-so-wonderful when in my 
opinion they have very little "actual benefit" from the use of MI. And 
I'd love to see some measures that could be used to determine whether 
there's benefit in the use of MI or not. Do you happen to know of any 
applicable measures?

But you're right to remind me that just because these are toy examples 
doesn't mean there aren't any real world uses.

Happy 2010!

Cheers,
   - Andreas



More information about the Squeak-dev mailing list