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
|