javacomparabledefault-method

Would it be possible to add default methods to Comparable without breaking Java?


I was thinking of proposing a feature request to add default methods called:

default boolean greaterThan(T o) {
    return compareTo(o) > 0;
}

default boolean smallerThan(T o) {
    return compareTo(o) < 0;
}

default boolean atLeast(T o) {
    return compareTo(o) >= 0;
}

default boolean atMost(T o) {
    return compareTo(o) <= 0;
}

to the Comparable interface as it would make the code much more readable - in my opinion.

However, I'm wondering if that would break code. Is there any code such as Lambda's that would break if we add default methods?

If I read this correctly I would assume that Lambda's would at least remain working, as long as they won't try to call the new methods, but I'm not sure. And I don't know if there could be any (obvious) other issues.

Please, no discussion about the possible feature request itself.


Solution

  • Unfortunately, @BasilBourque's answer is misleading, even though it quotes useful entities.

    There is no way this feature will be introduced by way of a subinterface. SortedMap/NavigableMap is not applicable: The default mechanism was not around when NavigableMap was introduced!

    At this point, it may be worthwhile to introduce some or all of the methods in NavigableMap as default methods in SortedMap, with implementations that work on sortedmaps and which will automatically end up getting overridden by any Map impls that implemented NavigableMap already (as they have overridden all of those in their impl).

    However, it means that 'Hey, look at NavigableMap which is analogous to SortedMap just like what you want to do to Comparable' is a misleading argument: Your proposal involves adding default methods. That just wasn't on the table back then.

    In the end what you want is 'almost, but not entirely, backwards compatible'. Oracle/Java Lang Architects tend to say that 'java does not break backwards compatibility' but this is a gross oversimplification and a borderline lie. If you ask a little further they will eventually admit that this is not true: The heart of the matter is that java weighs the cost of any backwards break (how likely is it, and what happens to code that did break it? If it silently still compiles and runs but does the wrong thing, that's horrible, if it is a trivial update that a refactor script can automatically apply every time, that's great - and then mix in the odds any given codebase stumbles on it, and you have an idea of 'cost'), vs the benefit of it.

    The costs are very minor here. It is extremely unlikely any code base would break. However, if you want to actually propose this feature, it would help a lot to do some research and try to think of any library (or if you can't, look at the top 100 lists which various folks blog about, analysing e.g. github java projects as source material) to go through a bunch to try to see if the thing that happened with .isEmpty would happen with these methods.

    Then, there is some bad news: Proposing a java feature is exceedingly unlikely to succeed. For some perspective, as author of Project Lombok, someone who's spend many hundreds of hours reading mailing lists like lambda-dev, who has contributed a large part of the actual lambda syntax and conceptual basis, and has held conversations with multiple Java Language Architects at some length (mostly at java conferences), I've sent in a proposal which included a full patch for java itself, and all due updates needed for the JLS, which didn't break backwards compatibility at all, and it never got anywhere. Not even so much as a JEP.

    Last time I spoke to an Oracle engineer they did promise that things are a little bit better now, but that doesn't go particularly far: I don't know of any java feature around or on the horizon that was sourced by an outsider that got kicked straight to a JEP and got anywhere near the foreseeable horizon of java features in the past 10 years. From time to time someone (usually Joe Darcy or Alex Buckley) runs a project to 'add a bunch of small convenient language changes', such as Project Coin (that was 11 years ago, oof). The second take on this is Project Amber, which I think is meant to be a more continuous project vs. coin which had a specific short-lived timespan.

    The route to get this into java would presumably go through amber.