Traits approaching mainstream Squeak

stéphane ducasse ducasse at iam.unibe.ch
Sun Aug 28 08:04:21 UTC 2005


Hi Andreas

your question about the granularity is a question of style. What you  
see in the kernel is the work of adrian and is also
constrained by the bootstrap and the old hierarchy (which is an heavy  
constraint). You can browse the master of Adrian
(which is now on holidays for three weeks and cannot reply directly  
so I will try to reply fro him). http://www.iam.unibe.ch/~scg/Archive/ 
Diploma/Lien04a.pdf

Now for me a trait is a set of cohesive methods. Recently we tried to  
see how semi-automatic algo could produce traits and compared
with the manual traitisation of the collection hierarchy and the  
difference was that nathanael favored a really fine-grained which
are good for optimal reuse but I'm not sure that I want to have that  
since we have to find meaningful names for the trait (have a look
at the image of nathanael on the collection refactoring to see what I  
mean). I think that this was too much in that direction.


>> Yes, at the moment, we're using Traits lazily to avoid duplication  
>> and inappropriate inheritance. We are not actively refactoring  
>> other parts of the system at the moment. Doing so would probably  
>> make the merge into mainstream Squeak more difficult.
>>
>
> Out of curiosity: I studied the use of traits in the kernel classes  
> and it wasn't clear to me how you decide on the granularity of the  
> traits involved. Can you say more about this?
>
> For example, I think ClassDescription uses roughly 15 traits, many  
> of which seem only to be used by ClassDescription/TraitDescription  
> so there seems comparadly little reason to (for example) define  
> TCopyingDescription, TCompilingDescription, TPrintingDescription  
> etc. separately. Looking over the methods involved it almost feels  
> as if the decision for defining the traits has been done along the  
> lines of protocols / categories. Is this correct? In which places  
> have you been avoiding inappropriate inheritance?
>
> It seems to me that a valid alternative for avoiding inheritance  
> problems is instead of duplicating the Behavior/ClassDescription/ 
> Class hierarchy via TraitBehavior/TraitDescription/ClassTrait would  
> be to make  Trait delegate to an appropriate class description  
> (e.g., a trait uses a class description for managing the Behavior  
> side of things).

But delegation does not solve the problem. Reread the papers of  
nathanael, you would have to define all the methods in the class and  
to delegate to the delegatee and traits avoid precisely this problem.  
And define all the delegate methods in all the users of the  
delegatee. This is the same with
simulating inheritance with delegation. We can do it but this is not  
so good.

It seems that I do not get your point right. Now we should not  
generalize from what is in Behavior and TBehavior since we are  
thinking about changing it and also because we do not have all the  
freedom because of bootstrap concerns (I do not remember exactly what  
was the problem). Ideally we can have one traits reused in  
traitBehavior and Behavior. Look in the archive of the traits mailing- 
list (if any) we have been discussing that point with daniel.

> Can you say anything about how such a design would have affected  
> the definition of traits for these kernel classes themself?

"a trait uses a class description for managing the Behavior side of  
things)"
I do not understand exactly what you mean here.

> BTW, the reason I'm asking these questions is to get a better  
> understanding on how one uses traits effectively. Looking over the  
> current uses it struck me that using a large number of fine-grained  
> taits can make it actually harder to understand the system. At  
> least that was my feeling when I looked over the current structure  
> - none of the traits are fully defined internally and it's really  
> hard to go fishing for what you still need to implement to "make it  
> work" (I actually really miss state here - I think it would be much  
> easier if you could see that someone wrote this with having in mind  
> that "X would be an instance variable"). I tried playing with the  
> required browser but it felt non-conclusive to use (it felt like  
> there were random methods shown in the required category).

This is true that the granularity of the traits have an impact on  
understanding and reuse. And there is a tradeoff between reuse and  
understandability. I would favor understandability. This is the same  
if you use subclassing too much in ad-hoc way (cf. Collection  
hierarchy).
The collection hierarchy is difficult to change because there are all  
this overrides everywhere. So I favor traits as nearly complete and  
pluggable entities but this is not that easy.


> Also, since you are asking for "near term feedback" I think it is  
> critical that one be able to see which methods come from traits and  
> which one's don't. For example, I was curious if Class had any of  
> its own methods or if all of the methods come from the three traits  
> it uses[*] and also which traits are used by which classes (e.g.,  
> "all users of TVariablesClass").

Yes this is basic navigation that we want. Now with the current state  
of the browser our only chance is to have OB getting faster and been  
the base for future code browser.

>
> [*] Similar question here: What were the design criteria to make  
> Class use three traits that (I think) are not used anywhere else?  
> Which methods were left in class Class and why?


Note that refactoring an exisiting class hierarchy conserving its  
interface is much more difficult than building it from scratch. I  
know you know that
(cf. Tweak vs. Morphic).


> In general, I think it would be helpful if some guidelines could be  
> established for how to use traits in practice. Just knowing how and  
> why you decided to factor the kernel classes the way you did would  
> be a good start. Oh, and comments for the traits might be helpful  
> too ;-)

;)

I agree. I think that in as a start for use of traits I would focus  
on big reuse: RectangleMorph and Rectangle. And places where we  
duplicate
because we do not have other choices (inheriting from X but also  
needed Y) and not refactoring really existing classes since we have  
to deal
with the constraints of the first designers.

Stef

PS: Mike I forgot to say that we can always flatten away traits (this  
can be automatic)








More information about the Squeak-dev mailing list