Extension methods are shaping up to be a great addition to Scala. I have now used them in extensively in both the compiler and in my teaching, so far with few hassles. But there are two small issues that we might want to address before shipping Scala 3. (There’s also a larger one that we want to allow multiple type parameter sections, but this one is for later).
The first issue is the status of extension
as a soft keyword. That caused a bit of confusion . For instance you can have a method named extension
which you could call like this:
obj.extension(f)
But you can’t call it without a qualifier at the beginning of a statement like
extension(f)
since then the extension
is classified as a keyword. See Methods named `extension` cannot be invoked · Issue #10076 · lampepfl/dotty · GitHub for more details.
We could try to put extra effort in disambiguating, but the question is whether it’s worth it. It might be better to make extension
a hard keyword, like all other keywords that start a definition.
That would also offer a solution for the second problem: How to call an extension method as a normal method. That’s needed sometimes when we want to be explicit what method should be called. So far, the scheme is that an extension method
object obj:
extension (x: A) def fun(y: B): C
is encoded as the method
object obj:
def extension_fun(x: A)(y: B): C
So if fun
is defined in object obj
, you can call it as obj.extension_fun(a)(b)
instead of the usual syntax
a.fun(b)
It turns out that this user-facing naming scheme is a bit awkward. How do you prevent people from writing extension_foo
definitions themselves, or how do you prevent the compiler from getting confused by them? Which name do you import? What about overriding rules? And so on. It would be simpler if we could avoid the name-mangling of fun
. But then we need special syntax to express a direct call to it, since allowing both prefix and infix usages at the same time would lead to too much ambiguity. With extension
as a soft keyword, I was unable to come up with a convincing syntax. But with extension
available as a hard keyword there are new possibilities. Here’s one originally proposed by @smarter.
obj.extension(a).fun(b)
This follows the order in which things are declared: obj
, then extension
, then the first parameter, then fun
, then the second parameter, so it should be easy to remember. Also, the use of extension
makes it clear that we deal with an extension method, which makes it simpler to figure out what the syntax means. After all, the use case is quite rare, so a lot of readers will be puzzled when they see it.