Draft proposal: allow the use of relational operators on Comparable classes
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:
>>> 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
>> 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");
> 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!
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.
More information about the coin-dev