-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #9028: Introduce super traits #9032
Conversation
@@ -1304,6 +1303,9 @@ class Definitions { | |||
def isInfix(sym: Symbol)(implicit ctx: Context): Boolean = | |||
(sym eq Object_eq) || (sym eq Object_ne) | |||
|
|||
@tu lazy val assumedSuperTraits = | |||
Set(ComparableClass, JavaSerializableClass, ProductClass, SerializableClass) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SerializableClass
is identical to JavaSerializableClass
(it used to be different, but since 2.13 scala.Serializable is an alias of java.io.Serializable)
I like the idea overall, some remarks:
|
I can see some use cases for dropping classes, but the existing rules do not lend themselves to be generalized that way. We'd have to come up with a different concept what would get dropped when. That said, I believe the issue with traits is a lot more severe than the issue with classes. So I am not sure we need to go further than just traits. |
Right, so the conservative thing to do would be to not get this in 3.0 in case we come up with some different rules, but maybe keep the special case for Serializable/Product/... since those are the most common offenders? |
If we change Serializable and Product we already have to buy into the whole scheme. The hairy part is to develop rules what to drop when, and this is already exercised by those two. It feels a bit ad hoc to me to just keep it to those two classes. Whereas restricting it to traits is clearly a step in the right direction (and maybe the only one we have to take). |
Would/could this help typing of collections? To e.g. improve the inferred type of Starting dotty REPL...
scala> Seq(List(0), Vector(0))
val res0:
Seq[scala.collection.immutable.AbstractSeq[Int] &
scala.collection.immutable.StrictOptimizedSeqOps[Int,
[X0] =>> List[X0] | Vector[X0]
, List[Int] | Vector[Int]]
& scala.collection.generic.DefaultSerializable] = List(List(0), Vector(0)) |
Isn't the problem of too narrow inference already solved for most cases with the |
@SethTisue With the latest changes:
@Odomontois This also shows that the problem is more general than what can be solved with enums. |
I also don't really see the relation between the keyword Maybe |
A super trait is a trait that is intended to be used specifically as a super trait of some other traits or classes, not as a type by itself. I first found it a bit weird, but now find it quite natural and better than having to invent another keyword. |
I'm not very convinced by this proposal. I understand the problem it solves, and I agree that it would be nice if this problem was solved. However, I don't think this proposal is an appropriate solution. My main concern is that this seems to be a language feature whose only purpose is to alter type inference. I do not think there is any precedent for that in Scala. It is concerning to me because type inference in general is not specified at all. So now we have one specific language feature, which needs a specification, whose effect is to alter a process that is completely unspecified. How does one do that? I do not think it can be done. |
Perhaps it's a secondary concern, but I think it could also lead to better Scaladoc, since generated Scaladoc could present the "main" traits first and more prominently, and the super traits secondarily. This would certainly make the Scaladoc for the standard collections more digestible. |
Even after a couple weeks of rolling the name "super trait" around in my brain and trying to get used to it, I remain highly uncomfortable with it. "Superclass" is one of the most established words in all of object-oriented programming. To introduce "super trait" but giving it a significant difference in meaning is a bad move, I fear. Some Googling shows that in a Scala context, both of the forms "supertrait" and "super trait" are commonly used, simply to mean any trait a type inherits. That's exactly what one would expect it to mean, and exactly how people are already using it, given how established the term "superclass" is. @odersky "supertrait" is even already used that way in your own book. |
Yes, and it is used in exactly that sense here! Every trait can be a super trait. By adding EDIT: To use an analogy with human parents: Lisa is the mother of Paul, but one can also say Lisa is a mother. One can even say mother Lisa (even though then she's most likely not a mother of someone, but that's another matter). |
The topic of
Is the separation between "materials" and "shapes" now enforced? Has it (can it) lead to simplification of algorithms for subtyping and/or type checking in Scala (i.e. Dotty)? |
|
Good point. We should do this, and I agree that it would help immensely. |
and eliminate super traits in widenInferred
Drop supertraits only if they are a mixin to something else (which is not a supertype of the supertrait itself).
This can be added in a backwards compatible way to cross-compiling sources
The idea is that some traits the 2.13 standard library should get annotated with @superTrait. I added the annotations to our version in the community build. Until that is done, we assume that the annotated traits are super traits by adding them to the assumedSuperTraits set.
I'd like to get this into 0.25. I think the benefits of this change are very promising and we should gain experience sooner rather than later. |
May I suggest using Additionally, note that the current documentation of mixin-class-composition starts with "Mixins are traits which are used to compose a class", so this seems in line with scala's terminology. |
I can't come to terms with the name "super trait". As already explained by @SethTisue and @smarter, "super trait" is already used for a more general concept than what has been implemented here. Yes, every trait can be a super trait; that's not the issue. The issue is that every trait is already a super trait, for the already widely used meaning of super trait. And even if "super trait" should mean this new meaning here, there is no way that "super class" is going to change from its decades-old meaning, so now users are even more confused because a "super trait" is not to be inferred, but a "super class" is inferred. How do you teach the difference between a super class and a super trait? I don't even understand how "super trait" can even be considered. The only reason I saw was "because the keyword already exist" with everything else sounding more like rationalization than intended design. There was this:
How do you reconcile that with the fact that the entire PL world talks about super types? A super trait is specifically intended not to be used as a super type. Seriously? If the reason is "because the keyword already exist", I'd throw in "extends trait". It's a trait meant to be used in an "Mixin trait" is not bad. At least we don't have years of literature talking about "mixin traits" for something different than what this PR implements. I'll also throw in "no-infer trait" as an ugly-but-obvious name. |
Chiming in from the end-user peanut gallery: strong agreement with @sjrd -- this terminology is used far too widely, and far too casually, for this to be any sort of good idea. It's guaranteed to cause confusion; worse, it's guaranteed to cause miscommunication, and speaking as someone who use Scala every day in a corporate environment, that's always my worst nightmare. Choose some jargon instead -- "mixin trait" would be fine, just something that isn't already laden with incorrect connotation... |
No description provided.