A recent document revealed some possible language changes that are being proposed. One of these is is extension methods.
Extension methods
Extension methods allow a user to 'add' a method to an interface or class that you don't control. The original document is linked with BGGA closures. And was followed up by Peter Ahe (broken link).
The classic example of the proposal is as follows (known as use-site extension methods):
// in the application import static java.util.Collections.sort; List list = ... list.sort();
Thus, the sort method appears to be a method on the list, even though we haven't actually changed the List interface. When it is compiled, the extension method is removed, and replaced with the static method call.
Peter Ahe pointed out some flaws with this design. He also proposes declaration-site extension methods:
// in the JDK public interface List { void sort() import static java.util.Collections.sort; ... } // in the application list.sort();
In this case, it is easier for the user to find the implementation of the sort method, as it genuinely is a method on the interface, just one implemented elsewhere. Unfortunately, the downside is that now only the JDK authors can add methods to the List interface in this way.
My proposal is that the freedom given to the user by the use-site approach is far more desirable, but the possible side-effects are nasty. My preference would be to add a visible marker to show that this isn't a regular method:
// in the application import static java.util.Collections.sort; List list = ... list.do.sort();
Note the '.do.'. This provides the user with the clear readability to show that something 'out of the ordinary' is going on.
In addition, I would argue that the static method should be marked to indicate that it can be used as an extension method, probably using an annotation:
// in the JDK public class Collections { @ExtensionMethod public void sort(List list) { ...} }
This provides the final piece of the puzzle, preventing innapropriate methods from being used as extension methods. While it does suffer from the same issue of pushing control back to the library author (the JDK), it avoids the issue of which methods get added to the List interface.
The point is that as many methods as appropriate can be tagged with @ExtensionMethod. There is no conceptual overhead in doing so, and it doesn't expand the conceptual weight or complexity of the ListInterface itself.
Summary
I've outlined an alternative proposal for extension methods, that tries to focus on freedom for users, without compromising readability or allowing confusing options.
Opinions welcome, as always :-)