-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Change extension method syntax #7557
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
Conversation
Yes!!! |
What's the rationale for preferring this over something like:
|
What's the rationale for preferring a extension [T](xs: List[T]) |
Well unless you want an |
@bishabosha Why not import individual extension methods by name? IMHO the object is purely a strange implementation detail, why would a top-level extension method not be imported with def (i: Int) inc: Int = i + 1 vs. extension (i: Int) {
def inc: Int = i + 1
} |
Regularity. If a |
@neko-kai It's too late to claim Besides, these things are givens, they are available in the implicit scope of companion classes and have to be imported as using import given. So it's better to make that clear in the syntax, I believe. |
The grouped extension method syntax always creates a wrapper object, which is not composable with existing Scala langauge features. (1) It is impossible to declare a group of abstract extension methods in a trait and later implement them in a class. (2) It's impossible to bind grouped extension methods to a known object/class/trait (3) It's impossible to split grouped extension methods to a trait, and mixin the methods in a known class or object. In contrast, if we allow an object/trait/class may have 0-n extension clauses (each is a grouped extension), we may avoid the problems above. |
@liufengyun The object is actually needed for implicit scope semantics. E.g.
To make |
To abuse the keyword object List extends [T](xss: List[List[T]]) with
def flatten: List[T] = ...
Depending on whether given extension (x: String) {
...
}
given StringOps extends (x: String) {
...
} It's just an anonymous/named given object with 0 templates and 1 extension clause. |
I'm sorry, but "too late" in what time-context? FWIW, I proposed using |
About 10 years too late 😉 |
We could make individual extension methods also obey implicit scope. Why not?
I think that's not a big issue, because due to overloading the names will be available most of the time anyway - it's also extremely intuitive for the user to be able to import methods from a group definition by their name AND easy for the IDE to find these methods and perform auto-import, for an anonymous given extension object how would an IDE even be able to import it selectively, if it's not referable? |
Comparing the wrapper objects for specificity is not enough; we should also look at the resolved methods themselves.
Disallow the previous syntax ``` given (x: T) ... extension methods ``` Require instead ``` given extension (x: T) ... extension methods ``` This avoids the confusion with given instances for types in parentheses and makes i7515.scala compile. To allow building with 0.20rc1, we allow the old extension syntax if it comes with a name. E.g. the following is still allowed, but will be dropped once we have bootstrapped with this commit present. ``` given ops: (x: T) ... extension methods ```
3354c65
to
0933b9c
Compare
It would introduce more coupling and make things more complicated. So I am against it in principle, but even more so now where we want to get to feature freeze. There's no time anymore for considering large and sweeping changes. |
Allow `end given` as an end marker for anonymous givens. These could not have an end marker before. Based on scala#7557.
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.
Otherwise LGTM
It's now
instead of
I hope that makes it easier to read and to search for.