Hi Stef,
Indeed you'd normally not double apply a trait. I want to do that here
for explanatory purposes, to show that a field is the melding of two
groups.
As it turns out, this double application merely highlights my
underlying issues. My problems would still be there whenever I wanted
to compose traits that shared requirements.
I had understood the "symmetric composition annihilates conflicting
methods" in "Traits: composable units of behaviour" to mean that the
composition would not have such methods _at all_. In Pharo, if you
have two traits S and T, and a common method m, the composition S + T
does contain m. If S and T implement m differently, the resulting m is
"self traitConflict". If both S and T implement m as "self
requirement", the resulting composition's m is also "self
requirement". That surprised me, but it does actually make sense. It
does mean that (S + T) != (S - m) + (T - m).
What I'd also expected is that aliasing (say, S @ {#m -> #z}) would
mean "the resulting composition does not understand m". But it does.
So in my case, I had expected that TGroup @ {#identity->#zero. #* ->
#+. #inverse->#negated} would result in a Trait that didn't define
#identity or #inverse, and that TGroup @ {#identity->#one.
#inverse->#reciprocal} would likewise not define #identity or
#inverse. Then resulting composition would have no conflicts, and
would simply understand #(#* #+ #negated #reciprocal #one #zero).
frank
On 30 May 2013, at 7:51, stephane ducasse <[email protected]> wrote:
> Hi frank
>
> normally it does not make sense to use two times the same trait. So I do not
> really understand
> how it could work.
>
> So now when you have two traits
> T1
> T2
>
> minus lets you erase selectively one message x from T1 if it is also
> available in T2
> and without having to redefine it into the composite.
>
> Stef
>
>> I have a Trait TGroup that requires #*, #identity and #inverse. I want
>> to construct a TField by composing TGroup with itself. One TGroup will
>> form the operations #*, #one, and #reciprocal while the other will
>> form #+, #zero and #negated.
>>
>> I don't want #identity or #inverse, because these apply to one
>> operation, and it makes TField's API ambiguous. That's what
>> TraitExclusion is for.
>>
>> I had thought I could say
>>
>> (TGroup @ {#identity->#zero. #* -> #+. #inverse->#negated} + TGroup @
>> {#identity->#one. #inverse->#reciprocal}) - {#identity. #inverse}
>>
>> but TraitComposition >> #- says that exclusion binds tighter than +.
>> So in effect the above composition is the same as
>>
>> TGroup @ {#identity->#zero. #* -> #+. #inverse->#negated} + (TGroup @
>> {#identity->#one. #inverse->#reciprocal} - {#identity. #inverse})
>>
>> In short, to remove the undesirable #identity and #inverse I have to
>> exclude from both sides of the composition:
>>
>> TGroup @ {#identity->#zero. #* -> #+. #inverse->#negated} -
>> {#identity. #inverse} + TGroup @ {#identity->#one.
>> #inverse->#reciprocal} - {#identity. #inverse}
>>
>> My question is this: what is the reason for - binding more tightly
>> than +? Why is it _not_ desirable to have - distribute over +?
>