There is a very specific pitfall with ternary operators in statically typed languages which allow type coercions, like Java. Programmers like to refactor code like this to avoid repetition:
if(condition) { System.out.println(3);} else { System.out.println(4.5);}
This can almost be rewritten as:
System.out.println(condition ? 3 : 4.5);
Unfortunately, the two are not equivalent, as the first version prints 3
when the condition is true, whereas the second version prints 3.0
because the ternary expression needs to have a static type, so it's double
. In general with overloaded methods this can cause arbitrarily different behaviour, though it only rarely makes a difference; I only came across this once when writing an interpreter in Java, where a method like this had a bug because I was too eager to simplify it:
Object getDefaultValue(Type t) { if(t == Type.DOUBLE) { return 0.0; } else { return 0; }}
The refactored version unconditionally returns a boxed value of 0.0
as a Double
, because ... ? 0.0 : 0
coerces to double
before the result is coerced to Object
.
It's genuinely rare for this refactoring to cause a significant problem in code, so this isn't really an argument against having the ternary operator in your language. But generally no programmer ever wants two type conversions in a row (here, 0
gets coerced to double
then Object
) without making both conversions explicit, so it's something to be careful of. (Perhaps there should be a warning for serial implicit type conversions.)