Skip to content
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

Syntax change for type parameters of extension methods #7455

Merged
merged 4 commits into from
Oct 29, 2019

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Oct 27, 2019

The new syntax has the type parameters come first. I.e.

  def [T](xs: List[T]) append (ys: List[T]): List[T] = ...

instead of

  def (xs: List[T]) append [T] (ys: List[T]): List[T] = ...

Application is unchanged, so it is still

  xs.append[String](ys)

An argument for the old syntax is that it aligns definition and call syntax.
On the other hand, the new syntax maintains the general rule that parameter introductions
always com before parameter uses. The decisive argument to switch is to be consistent
with the new collective parameter syntax, where append would be written like this:

  given [T](xs: List[T])
    def append (ys: List[T]): List[T] = ...

To avoid misalignment of type parameters between definition and call syntax, we considered
disallowing explicit type parameters for extension methods altogether, and to require
that the method is called as a normal method instead. But that would not work for anonymous
givens as in the last exaple above.

The new syntax has the type parameters come first. I.e.
```
  def [T](xs: List[T]) append (ys: List[T]): List[T] = ...
```
instead of
```
  def (xs: List[T]) append [T] (ys: List[T]): List[T] = ...
```
Application is unchanged, so it is still
```
  xs.append[String](ys)
```
An argument for the old syntax is that it aligns definition and call syntax.
On the other hand, the new syntax maintains the general rule that parameter introductions
always com before parameter uses. The decisive argument to switch is to be consistent
with the new collective parameter syntax, where `append` would be written like this:
```
  given [T](xs: List[T])
    def append (ys: List[T]): List[T] = ...
```
To avoid misalignment of type parameters between definition and call syntax, we considered
disallowing explicit type parameters for extension methods altogether, and to require
that the method is called as a normal method instead. But that would not work for anonymous
givens as in the last exaple above.
@odersky odersky requested a review from allanrenucci October 28, 2019 09:21
@anatoliykmetyuk anatoliykmetyuk self-requested a review October 28, 2019 15:12
@anatoliykmetyuk anatoliykmetyuk self-assigned this Oct 28, 2019
Copy link
Contributor

@allanrenucci allanrenucci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a neg test:

// dotc -Xfatal-warnings

def (self: T) foo[T] = ??? // error
def [T1](self: T1) bar[T2] = ??? // error

if (in.token == LPAREN)
try (paramClause(0, prefix = true) :: Nil, Method | Extension)
finally newLineOpt()
def extParamss = try paramClause(0, prefix = true) :: Nil finally newLineOpt()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: def extParamss() since the function is effectful

xs.foldLeft[List[T]](Nil)(_ ++ _)

def (x: T) + [T : Numeric](y: T): T =
def [T: Numeric](x: T) + (y: T): T =
summon[Numeric[T]].plus(x, y)
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As usual, type parameters of the extension method follow the defined method name. Nevertheless, such type parameters can already be used in the preceding parameter clause.

This need to be updated. Also I would add a paragraph about the position of explicit type parameters at call site.

@yinshurman
Copy link

Aha, another weird special rule which breaks again the consistency of the language.
it just looks like the type parameter T belongs to a anonymous method rather than the append.

another funny thing is that to support
"the general rule that parameter introductions
always come before parameter uses" , scala now is full of special rule and breaks the logic that a parameter always belongs to and hence comes after some thing like function or class.
besides, to support this weird special exceptional syntax, you introduce another special limits.on extension methods,and the final syntax becomes quite ugly.

@odersky odersky merged commit b44c6af into scala:master Oct 29, 2019
@odersky odersky deleted the change-extmethod-tparams branch October 29, 2019 10:02
@anatoliykmetyuk anatoliykmetyuk added this to the 0.20 Tech Preview milestone Oct 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants