Renaming @mixin?

While we’re at it can we please change the name of “mixin”? I don’t recall it being discussed. The name makes no sense to me. Every trait is a mixin.

1 Like

While we’re at it can we please change the name of “mixin”? I don’t recall it being discussed. The name makes no sense to me. Every trait is a mixin.

Of course. Traits play a dual role, as mixins to classes and as types that can be used stand-alone. How would you name a trait that is typically only used in its mixin role, but not as a standalone type? That’s the term we are after.

The approach here is to have an annotation that describes a property, and then use that to affect behaviour.

// Note: Type inference won't choose this
@mixin
trait X

Unless the property is super-clear and unambiguous, or many behaviours will change according to the annotation, I believe it would be clearer to use an annotation that describes the behavioural change instead. So in this case it could be something like:

@dontInfer
trait X
1 Like

On https://github.com/lampepfl/dotty/issues/10239 I suggested the term “auxiliary.” I’ll quote my reasoning:

The difference between traits like Product and HasSummaryAndDetailStrings
or SeqLike is not whether they are a mixin. And if I have a list of things
that only have Product in common I want it to be inferred.

The question should only be what to infer when there are other types to
infer. So the question is about making some traits second-tier when
inferring a union type or LUB.

Hence I would use a name that suggests secondary-ness, like auxiliary.

2 Likes

I think mixin is fine, but if we were going to change the name I would pick background because you want the trait to stay in the background unless you explicitly reference it. (Or uninferrable if we want to be really precise and don’t mind a little more typing.)

I don’t like names that talk about not inferring it, for two reasons:

  1. It’s not true that it should never be inferred. It should only not show up as part of a LUB / union type inferred when there is something better and more on target to infer. For example if you assign something of type Product to a val, the val should be inferred as Product too. Product is only uninteresting when it’s “in the shadow” of a more interesting type.
  2. The objective is not to start creating a sub-language for tweaking the type inferencing algorithm and giving it hints. The intent is to make the type inferencer aware of a unique category of types so that it acts more wisely. What we need to identify is what is the nature of that category? Why and how is it special?
    Once again, I would argue that the direction we should be looking in for names is describing that “secondariness.” I happen to like Auxiliary but any synonym would make sense to me.

If you have a different suggestion as to what exactly is the nature of this category of traits that should not be inferred in certain circumstances (and perhaps a better articulation of what those circumstances are), I’d love to hear it.

I thought of a different solution: Rename @mixin to transparent. One advantage is we already have the modifier. For inline methods it states that the return type of the method is disregarded in the type of the expansion. The proposed new meaning is quite close to this.

For traits, transparent would state that the trait is disregarded when computing the lub of subclass types.

2 Likes

What about @shy? It is short and somehow explains its usage.

PS: I don’t like transparent. In methods it makes types more precised, but in this context it will make them narrower. It is not big deal thou but looks little unsound for me.

4 Likes

I believe that this concept matches the idea of the Decorator pattern - these traits are intended to provide specialised behaviour without affecting the parent class that it is mixed into. The specialised behaviour is often recovered by instanceof checks, such as providing an iterator over the fields for an arbitrary case class, or simply to share common implementations.

So I think that @decorator makes sense

I also think that @mixin is confusing as an annotation for traits. When I first saw it, it made me think that the semantics of traits were somehow modified and now there are traits that somehow aren’t intended to be mixed-in.

Between super trait and @mixin trait, I have preferred super trait. Both reuse old terminology, but the explanation that “super traits are only intended to be used as supertypes” is much more convincing to me. If I hear “mixin trait”, Product (which is now annotated with @mixin) is the last thing that comes to my mind. First and only thing which does are traits which are intended to be stacked in the sense of the stackable trait pattern.

Personally, I think that introducing a new word here, such as @shape, would be for the best. New words have the advantage of not coming with any preconceived notions, which tends to make everyone look them up and later on, adopt them.

1 Like

I really liked japgolly’s “dontinfer”. So, in the spirit of that…
dontlub
lubexclude
lubinhibit
avoidlub
sanslub
lubnono
hatethelub
lubthisanddie
antilubbrigade
landhoyelubbers

1 Like

Another name for consideration: @typeBoundOnly. It’s inspired by @constructorOnly.

I agree it should capture the fact that it’s influencing type inference (@lubexclude or similar). I also kind of like @shy because it’s short and it doesn’t imply it’s disappears, like someone might assume @transparent implies (e.g. it’s compile-time only).

The problem with “transparent” and “opaque” is it’s ambiguous what the subject is: a glass having the quality of “transparent” makes what’s behind it very visible but the glass very invisible. Opaque types builds on type members/type aliases, where there never was a real, runtime class, but now you can’t dealias it - it’s opaque. With @transparent trait Foo, is that the new way to say @compileTimeOnly trait Foo?

That said, it’s better than @mixin and super.

1 Like

Has @implementation trait been suggested yet? It’s a trait you mix in solely to inherit the method implementations it contains. The name also suggests an “implementation detail” trait, not supposed to leak into interface types.

7 Likes

I suggested impl trait a while ago.

4 Likes

No one has any thoughts about my suggestion, or the arguments I made for it, either for or against?

@bundle trait because it is really there to provide a bunch of methods, unless you specifically want it as a type

If you’re talking about @auxiliary, I think it’s way too vague. There are many ways something may be auxiliary, and that name does not give us any information on the intended meaning of the annotation. Not even a mnemonic hint.

1 Like

Since this is going to be rarely used and most people will not understand what it means, the name does not need to be short, but rather needs to be as clear as possible. Therefore:

notIntendedForIntersections

1 Like

Another possibility could be @augments or @augmentation, taken from the YANG data modelling language where it is used to add fields into another structure.

Or if the annotation is meant to indicate that the trait is only used in a mixin role, then what about @mixin-only or @mixin-role?

I also quite like “@implementation trait”, and I also think that @mixin is probably okay.