Draft proposal: allow the use of relational operators on Comparable classes (original) (raw)

Joseph D. Darcy Joe.Darcy at Sun.COM
Tue Mar 17 15:12:14 PDT 2009


Vilya Harvey wrote:

2009/3/12 Kevin Bourrillion <kevinb at google.com>

On Wed, Mar 11, 2009 at 2:11 PM, Neal Gafter <neal at gafter.com> wrote: Vilya-

I suspect that if you narrowed the scope of this proposal to just enum types, it would have a much better chance of getting accepted for project Coin. To the general proposal, I believe the problem of conflicting meanings of <=, >= and == make it a non-starter.

I tried implementing the change & it was remarkably simple - without having looked at any of the openjdk code before, it took me just one evening; hats off to the compiler designers! However even the first bit of example code I wrote to test it with looked a bit strange: String a, b; ... if (a < b)_ _System.out.println("a < b");_ _else if (a > b) System.out.println("a > b"); else if (a == b) System.out.println("a == b"); else System.out.println("a.compareTo(b) == 0")'; It seems really odd that the else clause is actually reachable, but of course it is. I suspect that would catch a lot of people out. So given that experience and having read everyone's comments, I've come to the conclusion that the proposal would only make sense if it was part of a larger plan that included changing the meaning of == and !=. That would be such a breaking change that I doubt it will ever happen, much less in the jdk7 time frame, so I'm withdrawing the proposal. Thanks a lot to all of you who provided me with feedback! Vil.

If support for using relational operators on declared types were to be added, I agree that leveraging implementations of the Comparable interface would be the right approach. However, I also agree that the "==" and "!=" semantics issue is sufficiently large to block the proposal as a coin.

A few other numerical wrinkles, as Neal noted earlier in the thread floating-point comparison does not define a total ordering of values because NaN is neither, less than, greater than, nor equal to any floating-point value, including itself. Therefore, if a and b above were double or float, the last else clause would actually be reachable too whereas the final else clause would not actually be reachable if a and b had integral types. Some classes can have a natural ordering that is inconsistent with equals, such as the BigDecimal. In BigDecimal, the same numerical value can have multiple representation, such as 100 * 10^0 versus 10 * 10^1 versus 1 * 10^2. These are all "the same" under (compareTo == 0) but are not .equals with each other, making replacement of == with (compareTo == 0) conceptually problematic for another reason than object equality.

As an aside, I've considered whether it would be worthwhile to include an "@NaturalOrderingInconsistentWithEquals" annotation in the platform to flag the classes that have this quirk. Such an annotation could be used to various checkers to find potentially problematic uses of such classes in sets and maps.

-Joe



More information about the coin-dev mailing list