(To answer your question, a type system should be sound unless and until the user explicitly requests otherwise, easy to use, but above all consistent)
Enum types didn't exist in Java when the Comparable interface was implemented. That's why some API's look old-school by comparison because newer language features didn't exist yet.
That could be stated about pretty much every feature added since Java 1 really, it's not like the blub paradox has disappeared from our reality. How do you know that you wanted union types when you've never used a language which had them (and had features hindering such a conceptualisation, C-style enums are not really helpful there, even less so when extended the way Java did)
My counterargument would be the popularity of annotation-based libraries in Java. An annotation is basically a place where the official type system has proven inadequate.
http://ceylon-lang.org/documentation/1.1/tour/types/
Compared to union/intersection types, I find myself craving higher kinded types less frequently. I do feel the absence strongly, however, when I'm writing tools. I think the lack of higher kinded types manifests in the Java community as inferior libraries (eg ORMs) that require more manual-feeding of information via annotations or extra parameters to methods.
When you become used to a given language, you start to reason in its terms. A programmer who is used to Java is used to its shortcomings and will not miss Lisp macros or dynamic types.
To be fair, I can think of another functional language starting with "O" guilty of exactly the same thing...
(This idiom is a bit of a historical error. It would be better if compare returned a variant with three cases for less than, greater than, and equal. But it's a well-established idiom at this point, and unlikely to change.)
Eiffel is similar to ocaml : http://www.infor.uva.es/~felix/referencia_smart_eiffel/libra...
Does anyone know the advantages of the above signature over the Haskell alternative? Because this seems to be more obvious and easier to read. So there are more than one language guilty of using a ternary operator for compare.
Haskell does define the appropriate constructors, rightly so: https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-O...
data Ordering :: *
Constructors LT EQ GT
Historical reasons, mostly. The only practical advantage I can imagine is that it's a bit shorter to implement a reverse comparison, since you just multiply by -1.