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

State all known limitations of right-associative extension methods #19210

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,36 @@ For instance, the `+::` method above would become
This expansion has to be kept in mind when writing right-associative extension
methods with inter-parameter dependencies.

An overall simpler design could be obtained if right-associative operators could _only_ be defined as extension methods, and would be disallowed as normal methods. In that case neither arguments nor parameters would have to be swapped. Future versions of Scala should strive to achieve this simplification.
This expansion also introduces some inconsistencies when calling the extension methods in non infix form. The user needs to invert the order of the arguments at call site manually. For instance:

```scala
extension [T](x: T)
def *:(xs: List[T]): List[T] = ...

y.*:(ys) // error when following the parameter definition order
ys.*:(y)

*:(y)(ys) // error when following the parameter definition order
*:(ys)(y)
```

Another limitation of this representation is that it is impossible to pass the
type parameters of the `def` explicitly, (unless called in prefix form). For instance:

```scala
extension (x: Int)
def *:[T](xs: List[T]): List[T] = ...

xs.*:[Int](1) // error when trying to set T explicitly
Copy link
Member

@bishabosha bishabosha Dec 7, 2023

Choose a reason for hiding this comment

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

this still works:

*:[Int](xs)(1)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I only stated the cases that do not.

Copy link
Member

Choose a reason for hiding this comment

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

right, but you state that its "impossible" - but it is possible, just not how might be expected

```

The expansion of right-associative extension methods also affects the order in which contextual parameters can be passed explicitly.

Group extension can also behave unintuitively, in general all extension in a
group are extension on the receiver. Except if one of these extensions is a
right-associative extension method, in which case that one is an extension on the type of its argument. For instance:
```scala
extension (a: Int)
def :+(b: Long): Long = ... // extension on Int
def +:(b: Long): Long = ... // extension on Long
```