[squeak-dev] On traits composition

Eliot Miranda eliot.miranda at gmail.com
Tue Dec 8 20:26:44 UTC 2009


On Tue, Dec 8, 2009 at 11:49 AM, Igor Stasenko <siguctua at gmail.com> wrote:

> 2009/12/8 Colin Putney <cputney at wiresong.ca>:
> >
> > On 8-Dec-09, at 9:34 AM, Igor Stasenko wrote:
> >>
> >> Why?
> >> Can composition be an ordered collection of traits, so, they applied
> >> in sequencial order to class?
> >> Mixins use an inheritance chaining to achieve same effect.
> >> But traits don't using inheritance, and that's, i think, the main
> >> difference between them and mixins, but not the order of composition.
> >
> > One of the defining features of Traits is that composition is
> commutative.
> > The order doesn't matter because the composition of any two traits is an
> XOR
> > operation on the methods that each Trait defines. Any method that is
> defined
> > in both the Traits does not show up in the composition.
> >
>
> It shows up.
>

but as an error.  There isn't any way of removing a method.  Were foo
inherited from some superclass then unless the error method is generated
there would be no indication that there was a conflict between the two
traits defining foo.  So traitError is a more specific version of
shouldNotImplement.

foo
    self shouldNotImplement

is not as descriptive (it could be expressing the class author's intent) as

foo
    self traitConflict

but both are equivalent; they raise run-time errors saying "this method
shouldn't be here".  That's not the same as saying the conflict shows up as
a useful method; it doesn't.



> Trait named: #TFoo
>        uses: {}
>        category: 'WeirdExperiment'
>
> Trait named: #TBar
>        uses: {}
>        category: 'WeirdExperiment'
>
> now add method #foo to both of them.
>
> Object subclass: #TFooBar
>        uses: TFoo + TBar
>        instanceVariableNames: ''
>        classVariableNames: ''
>        poolDictionaries: ''
>        category: 'WeirdExperiment'
>
> browser shows:
>
> foo
>        self traitConflict
>
>
> TFooBar methodDict a MethodDictionary(#foo->(TFooBar>>#foo "a
> CompiledMethod(1916)") )
>
> IMO this is a minor matter, not the design cornerstone.
> If two or more methods conflicting there can be following choices:
> - take a first one
> - take the last one
> - take none (yours )
> - include method with error signaling (current implementation).
>
> I think that first two is much more useful in practice, not the last two
> ones.
>
> As to me, there is not much sense in making them commutative, since
> when you have a conflict, you are doing something:
>
> t1 - {#a} + t2
> or
> t2 - {#a} + t1
>
> which now is a mix of non-commutative #- operator with #+ .
> or can i assume that following should always yield true:
> t1 + t2 - {#a}  =  t1 - {#a} + t2
> ?
>
>
>
> > The fact that Traits don't use inheritance chaining is a consequence of
> this
> > definition, not the defining feature its self.
> >
> > Colin
> >
> >
>
>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20091208/dd1a34d6/attachment.htm


More information about the Squeak-dev mailing list