Traits vs. Interfaces (was Re: election details *PLEASE READ*)

Andreas Raab andreas.raab at gmx.de
Sat Feb 24 09:21:59 UTC 2007


J J wrote:
>> The main problem is the (mostly) static nature of interfaces in Java. 
>> E.g., declaring them is a pain, otherwise I would disagree. If you 
>> want to share a default implementation use a subclass - one of the big 
>> problems I see with traits is that their interfaces get so specific 
>> that an *alternative* implementation becomes effectively impossible 
>> (therefore completely loosing the point about interfaces as 
>> abstractions).
> 
> Does it have to be this way, or are you looking at a... less then 
> optimal use of a workable technology.

Of course it doesn't have to be that way. But one of the hardest things 
to do is to be honest about how particular features of languages 
*actually* work out. It's like MI in C++ - of course there are ways of 
using it "right" it's just nobody seems to use it that way (although I 
will admit that my experience is dated - after having burned my fingers 
several times I never used MI again other than in the Java way, that is 
by using abstract virtual base classes).

[... snip ...]
> I hear what you are saying about "use a base class", but does my base 
> class still have to say "implements"?

That depends on your particular flavor of interfaces. BTW, I do see your 
point about Haskell but note that in your example you have both given 
the definition as well as the constraint on a particular interface - in 
my understanding this is more like specifying type algebra or pre/post 
condition and not as much about actually providing the code for the 
implementation.

> Either way, this feels to me like another manifestation of a problem I 
> always had with Java:  implementation inheritance.  I may make 3 totally 
> different window widgets, and by rights each one would "implement" a 
> draw API, but I will have to invent another class for them all to 
> inherit to avoid duplicating a bunch of unrelated code.  People reading 
> my code may wonder why "3DGameWindow" is in the same tree as 
> "TaskBarClockWidget", but it is just to save code duplication.

That's why I mentioned delegation. You could have an object 
encapsulating the drawing policy and have your three classes delegate to 
it. In which case you not only get the interface but also the ability to 
dynamically change the drawing policy - at the cost of (at least) one 
slot for the object representing the policy. To me, this is a much 
cleaner way of dealing with the problem you are describing while 
preserving all of the good properties of objects.

>> For example, look at TAccessingMethodDictDescription (which is simply 
>> the first in the browser) - it is practically impossible to 
>> reimplement this (or any other) of the current traits for the class 
>> kernel in any way that doesn't exactly follow the current 
>> implementation (like if TAMD is responsible for accessing the method 
>> dictionary then we should be able to reimplement MD access without 
>> affecting any other trait, right?).
> 
> Is this a problem with the technology (Traits), or the implementation?

There is not enough evidence to draw a conclusion yet. The evidence is 
that this implementation seems to have a problem towards that end and 
the implementation was strongly driven by the desire to eliminate code 
duplication (more so than to structure it into logical aspects). I think 
that the attempt to eliminate duplicate code at all costs using traits 
may ultimately lead to this effect simply because if you try to squeeze 
all the entropy out of the system then the result will be a static 
structure.

Interfaces on the other hand, precisely *because* of the overhead they 
require tend to be more minimal, therefore more abstract and therefore 
more easily to maintain and (re)implement.

> Well that is a good technique.  I don't personally see Traits as hammer 
> or a silver bullet, but I do think they (at least have potential to) 
> fill a hole [1].

Are we talking about a hole in Java or in Squeak? Your example only 
applies to Java, not to Squeak (which has had #=, #==, #~~ and #~= in 
Object from its very first day). For that particular problem we didn't 
need traits. Now, I'm not saying there aren't places in which traits can 
be usefully applied - in fact I am *dying* to see a good use case. One 
where they actually help to make things simpler, structures clearer, 
more easy to understand.

> But since Traits can't have variables, I would expect them to be useful 
> in many of the same ways Haskell type classes are.  I could be wrong, 
> but I hope I'm not and I can't think of a technical reason Traits must 
> create fragility.

I need to read more about Haskell's type classes - I never looked too 
closely at them. Do they actually specify implementation or is it all 
type algebra (like in your example before)?

> But I also wonder if it is sort of a "hot button" issue.  I mean, there 
> are things to be frustrated/embarrassed about here (e.g. releasing 
> something into the image that appears to have no means of maintaining).

Of course it is frustrating. But what is worse is that while the paper 
examples all look fine I just haven't been able to find an improvement 
in understanding or design when I look at the (admittedly only) example 
of a real-world use. If that is the future with traits then it is a 
bleak future indeed. And of course it is quite possible that tools are 
missing, that early explorations go wrong but at least we should be 
honest enough to reflect critically on the artifact that was produced 
and see what is right and see what is wrong.

Cheers,
   - Andreas



More information about the Squeak-dev mailing list