[squeak-dev] On traits composition

Igor Stasenko siguctua at gmail.com
Tue Dec 8 07:48:13 UTC 2009


2009/12/8 Andreas Raab <andreas.raab at gmx.de>:
> Folks -
>
> I'm working slowly through some of the traits test cases, and some of them
> simply make no sense to me. Currently, I'm in
> TraitCompositionTest>>testInvalidComposition and most of it seems very odd,
> for example:
>
>        self should: [self t1 @ { (#a -> #b) } @ { (#x -> #y) }]
>                raise: TraitCompositionException.
>
> This currently signals a TraitCompositionException 'Invalid trait exclusion.
> Aliases have to be specified before exclusions.' but note that the above
> doesn't *have* any exclusions, so what's the point here? From my
> understanding of traits, I would rather assume that:
>
>        self assert: (self t1 @ { (#a -> #b) } @ { (#x -> #y) })
>                = (self t1 @ {#a -> #b. #x -> #y}).
>
> Same goes for exclusions, e.g., instead of:
>
>        self should: [self t1 - { #a } - { #b }] raise:
> TraitCompositionException.
>
> I would rather claim that:
>
>        self assert: (self t1 - {#a} - {#b}) = (self t1 - {#a. #b}).
>
> Lastly, it's not clear to me why the requirement that aliases have to be
> specified before exclusions even exists. It seems pretty clear what the
> expected outcome is. Or is this just to keep a bit of conceptual clarity,
> i.e., that aliasing (@ operator) comes always before exclusions (-
> operator). From the implementation point of view it's actually simpler to
> support arbitrary compositions and if you're into this kind of stuff I see
> no reason to force superficial rules on you :-)
>
> Oh, and one more issue: I'm starting to question the idea that "conflicting"
> trait methods should create a trait conflict. It seems to me that "last one
> wins" would be more useful, i.e., if you have two traits t1 and t2 and use
> them via t1+t2 you get t2's version; if you use them via t2+t1 you get t1's
> version. You're always free to override the version if you don't like the
> result but I think that "last one wins" will be a useful outcome in more
> cases than raising an error :-)
>
+1. It should be more straightforward.
T1+T2
should mean 'apply T1 then T2', but not 'apply combination of T1 and T2'.
Its much easier to implement as well as easy to understand & follow.

Also, in Pharo list i suggested extension to exclusion operator:

in addition to:
T1 - selectorsArray "{ #sel1. #sel2 }"

also have:

T1 - T2

which should transparently behave as:

T1 - (T2 selectors)

and mean: apply all from T1 , except selectors in T2.

Btw, i am curious about one thing:
Since traits allowed to hold method for both instance side and class side.

Then suppose my trait having:
#isel1
#isel2
at instance side, and
#csel1
#csel2
at class side.

Now, how i can specify a composition, which applies my trait, except
#isel1 and #csel2 ?
So, final class should have #isel2 method at instance side and
#csel2 at class side, but not #isel1 and not #csel2.
And what is a correct syntax for defining such composition in class definition?

> Any comments are greatly welcome.
>
> Cheers,
>  - Andreas



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list