Traits approaching mainstream Squeak
stéphane ducasse
ducasse at iam.unibe.ch
Sun Aug 28 08:11:21 UTC 2005
I agree with daniel.
See my other email
On 28 août 05, at 00:02, Daniel Vainsencher wrote:
> Hi Andreas!
>
> Andreas Raab wrote:
>
>> 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?
>>
> I haven't done that myself, that's (IIUC) mostly Adrian's work.
> He's best qualified to describe his intentions. I personally
> definitely agree that there are many open questions about how
> Traits should be used, and a serious discussion about they've been
> used so far would be really helpful.
>
>
>> 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?
>>
> Adrian or maybe Stef are better suited to respond to that as a
> specific question. The general question is "What is the proper
> granularity of Traits?" My opinions: methods in a trait should
> implement a specific responsibility in a reusable way. To serve
> this, they should have a small requirements footprint, such that
> any class/trait that wants an implementation for this
> responsibility has to provide them anyway.
me too and may be what is in Behavior is too fine-grained.
> Here's another general question -
> In my opinion at the moment, and I'm curious what other people
> think, in the presence of Traits, there is no excuse for separating
> Behavior, ClassDescription, and Class into a hierarchy. The
> responsibilities each represents could be reused separately if they
> were Traits. So the only clearly compelling reasons to create
> classes become that you want to have instances with that shape and
> behavior. An abstract class doesn't seem to make too much sense. So
> when should we use Traits to replace inheritance as a mechanism for
> sharing implementation? always? Never except when needed to avoid
> duplication or the complexities of delegation?
>
>
>> In which places have you been avoiding inappropriate inheritance?
>>
> I for example think that the current inheritance of TraitBehavior
> and Behavior from PureBehavior is inappropriate, and should by
> replaced sharing the methods using a Trait usage. The reason for
> PureBehavior existing in the demo is historical - before Traits
> started functioning, that way of sharing implementation wasn't
> available. That change is going to happen before integration with
> mainstream, among things because it would make the Kernel hierarchy
> more similar to what is there now, therefore minimization
> integration costs.
>
>
>
>
>> 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). Can you say anything about how such
>> a design would have affected the definition of traits for these
>> kernel classes themself?
>>
> IIUC this proposal, it would require creating a class description
> for every Trait. But a ClassDescription inheriting from Behavior
> know too much and does too much - it is a full descriptor for
> object with behavior, which a Trait isn't and doesn't need. So the
> alternatives would be to either factor out ClassDescription
> responsibilities to a delegate that would serve both Classes and
> Traits, or to share the ClassDescription behavior via one Trait,
> instead of by parallel classes that use the same Traits. Delegation
> doesn't feel to me like the right solution because the interface is
> wide, and there doesn't seem to be an opportunity for exchanging
> the CD with a polymorphic alternative. I think the one Trait used
> directly might be nicer than the two classes sharing many Traits.
> An advantage of the current approach is that it makes the smallest
> change to the structure of the Class hierarchy.
>
>
>> 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
>>
> I'm not familiar with all of it. Lets discuss something specific,
> so we can learn from it. Lets look at some specific Trait that
> annoys you and see how it can be improved.
>
>
>> 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).
>>
> About the required browser -
> 1. Did you use the version I announced? an earlier beta had a
> critical bug, though it was in the other direction - sometimes
> showed too few methods.
> 2. Do note that requirements are a non trivial property to compute
> (including in our heads). One reason is that requirements are often
> inherited. For example, Object implements #stepIn: which self sends
> #step. Therefore, everything in the system that doesn't implement
> #step and does inherits #stepIn: requires #step.
>
> I think this, for example, points to a great example of non optimal
> use of inheritance to share behavior, that can be improved upon
> using Traits.
>
> Getting back to your questions:
> If you find specific cases where the requires browser is not doing
> what you expect it to, please let me know. It hasn't seen that much
> use, so there might be tests we've missed.
>
>
>
>> Also, since you are asking for "near term feedback"
>>
> That too :-)
>
>
>> 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").
>>
> Right. In the prototype this happened in two ways: non-locally
> defined methods were green, and under each class that has traits,
> in addition to those, there was a computed entry "-own-" that shows
> only local methods.
>
> Have a preference?
>
>
>> [*] 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?
>> 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'll let Adrian deal with these :-) he's on vacation, btw, so it
> might be a while.
>
> > In general, I think it would be helpful if some guidelines could be
> > established for how to use traits in practice.
> I think the best we can do at the moment is -
> A. Study and discuss the existing design examples - the collections
> restructure (I don't know if the code is available somewhere) and
> the kernel restructure as seen in the demo.
> B. Start playing with these new options in our own work.
> It's new, like Mike said, the patterns book for Traits has not yet
> been written...
>
> Keep up the good questions, and proposed patches welcome.
>
> Daniel
>
>
More information about the Squeak-dev
mailing list
|