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:
>>
>> 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