[Pharo-project] SimpleTraits - How can we have Traits/Mixins quickly?

Peter van Rooijen peter at vanrooijen.com
Mon Nov 29 16:38:44 CET 2010


On Mon, 22 Nov 2010 10:45:30 +0100, Marcus Denker <marcus.denker at inria.fr>  
wrote:

1) Those that block any change because Smalltalk is not supposed to be  
changed by mortals.

2) Those that want to go "beyond Smalltalk". But it has to be perfect!  So  
better do nothing.
     (Aka: The Squeak Desease). This is the far greater problem.

<old man story snipped>

Marcus, you are so right! We should not wait to *share*
until what we have made is perfect (or fully functional,
or polished or some other excuse for not sharing).

Let me tell you a story of my own.

I was at a Smalltalk meeting in Cologne a little while ago
and it was my first time there and I did not know the people
there. I thought: let me, as a newcomer, try to contribute
in return for their organizing effort and hospitality.

So I said I would be happy to show some code (a class) that
I had written and that I used a lot and found very useful.
They said please show us, so I browsed the class and its
tests and a few examples and showed most of the code and
answered a few questions and we had a little discusion.

During the break a few guys said to me we should have more
of these presentations, where someone shows code. I said:
so why don't you do that more? And you know what the core
answer was? Everyone is more or less ashamed to show their
code because they think it is not very good.

Will you believe that I was very surprised to hear that THAT
was the problem? My own code, which I showed, was ugly, incomplete,
unfinished, inconsistent in places. But I knew that it had value,
because it implemented ONE valuable IDEA effectively. I had
been using it for several years and always just implemented
what I needed the code to do.

I didn't care that other people saw my unpolished code,
in fact I was happy and hoped they would give me some
inspiration to maybe improve it, or more motivation to
share it more widely than I had done.

So I agree, imperfect solutions have value and
please do not feel afraid to share what is not "perfect"!


BABBAGE

But the Babbage in the story had a point too. Continuing on
something that you know you can't finish seems irrational and
the fact that his replacement projects were also unattainable
does not mean that he should have continued with the old stuff.

If you work only for yourself, you can of course do what you want.


TRAITS/MIXINS

But what about these traits? I don't understand what all the
fuss is about. Wasn't the point of Traits that it is *sooo*
frustrating to have to duplicate all kinds of code in various
classes, which wouldn't be necessary in a multiple inheritance
language? And *sooo* frustrating that we would love to refactor
Collections and stuff but we can't because of we only have
subclass inheritance?

But full-fledged multiple inheritance is too much work, too
big a step, or we could never agree on the semantics/details...


And isn't there a problem in that the browsers expect classes
and not traits and that it is too much work to change the tools,
expecially as they are moving targets?


If these are really the problems, then why can't we simply
allow a class to mix in another class? Could that be a 70%
(imperfect) solution, for 10% of the effort?

Class1 mixIn: Class2


CONFLICTS CANNOT EXIST

Class2 must be suitable to be mixed in with Class1 or the
operation fails. If it succeeds, the definition of the
second class is merged into that of the first.

If we change either class, these changes are acceptable only
if the two classes remain compatible for mixing and the
compiler must take into account the dependencies so that
when a mixed in class is changed, the compatibility is
verified and the receiving class is recompiled as required

ANY class can be mixed in to another as long as they
are compatible for mixing. No tools need be updated.
The class definition source will not change.

There WILL have to be a class method something like

mixInClasses

^
{Class2 . Class3}

Of course some smart person will teach the browsers about
this method but there is no requirement for this.
At first all that is needed is that the
compiler knows to use this method to make sure that
Class1 is compiled as if the mixed in classes were
part of its definition.

There will be NO RENAMING of anything to resolve conflicts.
Conflicts simply cannot exist. All the variable names
(instance, class, class instance, pool) in the definitions
of both classes will remain the same when mixing is done.

instance, class instance, and pool variables with the
same name in both classes can, by nature, never "clash".

Class variables will refer to the same variable in both
classes if both mixed classes inherit the class variable
 from the same superclass, or to a different one in each
class otherwise.

If a method with the same name exists in a class AND its
mixin (as will happen when you mix a class with at least one
method in to another), they must have the same definition.

Programmers defining classes for the purpose of mixing them
in will simply have to take these limitations into account.
This is nothing new or special; with subclass inheritance
there are also things you can and things you cannot do, and
the compiler already takes al the relevant rules into account
and enforces compliance.


HOW TO USE

When you have this mixin scheme in your image, you can start
with an empty Class2 or with Class2 being a copy of the Class1
and mix Class2 into Class1. The effect on Class1 is the same
since conflicts cannot exist.

You can then proceed to remove methods from either class,
add methods (if added to the trait, they will also be added
to the base), remove methods (removing only from the base will
have no effect), change methods (synchronized).

In short, you can gradually and incrementally reorganize
the code in your image, without changing any functionality.
All the existing tools for code management keep on working

Later on people will figure out to improve the browsers,
and to remove duplication in the compiled structures. But
for a start we can remove a whole class of source duplication
and this seems a worthy goal.


HOW MUCH WORK

SimpleTraits should not be more than a few days work for
someone reasonable familiar with the compiler infrastructure.
(Of course I have no idea but I can conjecture). Does
anyone think they would want to use it if it existed?

Who will build this and give a nice Christmas present
to the community? I hereby donate the design inasfar as
it contributes anything original, and provided it is
implemented and integrated in Pharo within 6 months :-).

Cheers, Peter

P.S. Traits/MixIns? For SimpleTraits, I would propose to
keep both names. We say we mix in (the compiler mixes in)
a class using Class1 mixIn: Class2.
The compiler finds the mixInClasses from the methods
with the same name.
When we talk about Class1 and Class2 in relation to each
other we call Class1 the base, and Class2 the trait (of
course both classes can conceivably play the other role
as well, in other mixin relationships, but we need not
concern ourselves with this at first and simply not
implement multi-stage mixin relationships although this
may become desired at some later point in time).

P.P.S. Stéphane, let me know if this SimpleTraits design
addresses what you require from a Traits system. I had dreamed
up this design some time ago but thought Traits were already
"there". Now it seems that Traits have somehow not "made it" into
Pharo and I believe with you that it is a shame not to have it.

P.P.P.S. Inherited elements (vars, methods) of a trait class are
(of course) part of what is synchronized and shared with its
bases so be mindful of what you inherit!




More information about the Pharo-project mailing list