Draft proposal: allow the use of relational operators on Comparable classes
Vilya Harvey
vilya.harvey at gmail.com
Tue Mar 10 09:09:18 PDT 2009
I've attached a draft of a proposal to allow classes which implement the
Comparable interface to be used as operands for the relational operators. So
for example if you had two Strings, a and b, you would be able to write
if (a < b) {
...
}
instead of
if (a.compareTo(b) < 0) {
...
}
and you could do the same with your own classes as well.
Thanks in advance for any feedback,
Vil.
-------------- next part --------------
Proposal to allow the use of relational operators with Comparable classes.
AUTHOR
Vilya Harvey <vilya.harvey at gmail.com>
OVERVIEW:
Feature Summary
---------------
Using the results of the compareTo method can be confusing: it's easy to
get the values the wrong way around. I propose allowing classes that
implement the Comparable interface to be used with Java's relational
operators, to help avoid this confusion.
Major Advantage
---------------
Clearer code.
Major Disadvantage
------------------
Could create some confusion with the equality operators as == and != would
still be checking for reference equality rather than using the results of
the compareTo method.
Would need to decide how to handle cases where Comparable objects could be
unboxed to numeric values (i.e. instances of java.lang.Integer, etc.). In
that situation, should you treat them as Comparable objects or should you
unbox them and perform a numeric comparison?
Alternatives
------------
It is currently possible to use the result of compareTo() directly and
that's a well known idiom, although still prone to the occasional mistake.
It is also possible to write utility methods isLessThan(),
isGreaterThan(), etc. which use the results of compareTo in the same way
as suggested above.
The isLessThan() et al. could be added to the Comparable interface,
although this would break a lot of existing code.
EXAMPLES
Simple Example
--------------
The simplest case is where an existing class already implements the
Comparable interface:
String a = ... ;
String b = ... ;
System.out.println("Is a < b? " + (a < b));
At present, the above would have to be written as:
String a = ... ;
String b = ... ;
System.out.println("Is a < b? " + (a.compareTo(b) < 0));
which is a bit less clear.
Advanced Example
----------------
The trickier details would be around handling of nulls and unboxing of
numeric objects.
String a = null;
String b = "hello";
if (a > b) { ... } // Throws a NullPointerException?
if (b < a) { ... } // Only throws a NullPointerException if
// b.compareTo(a) throws a NullPointerException?
Integer c = 10;
Double d = 10.1;
if (c < d) { ... } // Compile error or numeric comparison?
The above could be written in today's Java, with the consequences:
String a = null;
String b = "hello";
if (a.compareTo(b) > 0) { ... } // Throws NullPointerException.
if (b.compareTo(a) < 0) { ... } // Throws NullPointerException.
Integer c = 10;
Double d = 10.1;
if (c.compareTo(d) < 0) { ... } // Compile error.
DETAILS
Specification
-------------
This proposal would require changing the semantics of the relational
operators, to allow for the case of objects which implement the Comparable
interface as the operands. In this case, it is proposed that the operators
be treated as syntactic sugar for an invocation of the compareTo method of
the left operand with the right operand as an argument, with the result
compared to zero.
The expression
a OP b
where OP is any one of the four relational operators (<, >, <=, >=)
defined in section 15.20 of the Java Language Specification and both a &
b are objects implementing the Comparable interface; should be
de-sugared to
a.compareTo(b) OP 0
where OP is the same relational operator as in the sugared form.
In the case where both a and b are Comparable objects which can be unboxed
into primitive numeric types, it is proposed that the unboxing should be
given precedence. That is, the unboxing should be performed and the
operator be evaluated as per it's current semantics. This will maintain
the semantics of existing code.
No grammar modifications are necessary for this change. Likewise no new
bytecodes are needed. It can be implemented purely as a modification to
the compiler.
Compilation
-----------
As above.
Testing
-------
Library Support
---------------
This feature requires that classes implement the existing
java.lang.Comparable interface in order to be used with the relational
operators. No other library support is required.
Reflective APIs
---------------
No changes necessary.
Other Changes
-------------
None requried.
Migration
---------
Where existing code calls compareTo() and compares the result to 0, simply
replace that with the appropriate relational operator.
COMPATIBILITY
Breaking Changes
----------------
No existing programs would be broken by this change, providing unboxing
occurs before the comparison is performed.
Existing Programs
-----------------
Existing programs should be completely unaffected by this change.
REFERENCES
Existing Bugs
-------------
URL for Prototype
-----------------
More information about the coin-dev
mailing list