Totality at switch statements

Brian Goetz brian.goetz at oracle.com
Sun Jun 19 13:42:25 UTC 2022


> I haven't played with switch expressions, but I think of them kind of 
> like this but much more performant...
>
> int y = x == 0 ? 0 : x == 1 ? 2 : x == 2 ? 4 : x == 3 ? 6;

I encourage you to broaden how you think of this.  Yes, they might be 
more performant (though they might not be -- a good compiler can chew 
this up too), but that is is both a secondary, and a dependent, 
benefit.  The alternative is:

     int y = switch (x) {
         case 0 -> 0;
         case 1 -> 2;
         case 2 -> 4;
         default -> 6;
     }

which I'm sure everyone finds more readable.

The primary benefit is that you are using a simpler, more constrained 
concept.  A chain of ternaries or if-else can have arbitrary and 
unrelated predicates, and offers less opportunity for exhaustiveness 
checking.  It involves unneeded repetition ("x == <something>") which is 
a place for errors to hide in.  The fact that each predicate in the 
chain above is of the form `x == <something>` is neither mandated nor 
checked nor even obvious at first glance; this makes it harder to read 
and more error-prone; you could easily fumble this for "z == 2" and it 
would be hard to notice.  Whereras a switch has a distinguished operand; 
you are saying "this operand should match one of these cases", and 
readers know it will match *exactly* one of those cases.  That is a more 
constrained statement, and by using a more specialized tool, you can 
make the calculation more readable and less error-prone.

The performance benefit, if there is one, comes from the fact that you 
have performed a semantic "strength reduction", which is potentially 
more optimizable.  But that's a totally dependent benefit, one which 
flows from having written more clear, specific code in the first place.




More information about the amber-dev mailing list