Traits provide a means of composing an object’s functionality out of smaller, simpler parts. Verbs being limited in number, especially good ones, sometimes you want to compose two traits that share names. Today we’re going to look at how to resolve the dispute.
I have a soft spot for abstract algebra. I realised how we can consider a field to be the melding of two separate groups: we can construct the field of reals from the group of integers under + together with the group of integers under *, with a bit of stitching in the form of the distributivity laws. So let’s make a group:
Now we can compose the two traits. Er, except we’re going to compose
TGroup with itself! Name clashes galore! The
uses: argument to Trait creation shows a
TraitComposition, wherein we show how the two group structures contribute to the field structure. . We thus have
Note that aliasing –
#identity -> #zero – doesn’t remove the method from the Trait. This causes a bit of a problem. In the context of a field, we don’t usually talk of “the identity element”, because of course there are two group operations. We instead talk of the additive identity (“zero”) and the multiplicative identity (“one”). We call one operation “sum” or “+”, and the other we call “product” or “*”. Similarly, the two inverse operations are “unary negation” or “negated”, and “reciprocal”.
The only thing I dislike about composing the two
TGroups in this way is that aliasing doesn’t remove the conflicting methods: “identity” and “inverse” remain in the public API of
TField. But we can fix this, by excluding the ambiguous selectors:
We can’t avoid the awkward double-phrasing of the exclusion (
-). It would be much nicer if you could remove the methods from the composition:
but neither Squeak’s nor Pharo’s implementation of Traits permit this: exclusion removes methods only from the rightmost trait. Whether that’s simply a bug (in the sense of “gosh, no one’s thought of doing that”) or something intrinsic in the semantics, is as yet an open question.