I think the best way to provide this “simple case” extension method is to do it just as a syntactic sugar for a normal method call. The element in the last, singleton parameter list would be designated as the “this
”. It would look like so:
case class A(...)
def f(b: B, c: C)(a: A): D = ...
a.f(b, c) // de-sugars to f(b, c)(a)
The current proposal is in some ways already close to this, that it’s just a syntactic sugar. But the advantage of this is that it makes the very same methods methods easily chainable, in both scenarios
- using
.
as method application:sequence.map(plus1).filter(isEven)
- using
andThen
(or>>>
) as method composition:map(plus1) andThen filter(isEven)
class Sequence[A](...)
...
def map(f: A => B)(s: Sequence[A]): Sequence[B] = ???
def filter(p: A => Boolean)(s: Sequence[A]): Sequence[A] = ???
...
sequence.map(plus1)
// de-sugars to `map(f)(sequence)`, since
// * `Sequence` doesn't have a member `map` and
// * `map(...)(s: Sequence[A])` is in scope
sequence.map(plus1).filter(isEven)
// de-sugars to `filter(isEven)(map(f)(sequence))`
// and these same function can also be used on their own very nicely, especially with chaining
map(plus1) andThen filter(isEven)
Currently we have to nest method calls in parentheses, which is cumbersome, e.g.
filter(isEven)(map(f)(sequence))
I think this approach to having “extension methods” would be a good addition to Scala 3 and at the same time a great simplification to many use cases. But I’m not sure how big support this has, is there anyone who would like it too?