I agree with the “unpleasant asymmetry” part, but I’m not sure its fair to call 
it arbitrary.  The original design of switch statements deliberately embraced 
partiality, for non-arbitrary reasons; the design of expression switches 
deliberately embraced totality, again for non-arbitrary reasons (and with 
awareness of the ensuing asymmetry.)  I think it is more accurate to attribute 
the asymmetry not to arbitrary choices, but deliberate ones, specifically: the 
decision to reform switch, rather than create a 
new-and-almost-identical-but-not-identical construct (“snitch”), and have the 
two (or four or eight, as we discovered new mistakes) live side-by-side 
forever.  And, while there were many “quick-lets-fix-the-mistakes-of-the-past" 
suggestions for the ideal snitch semantics, I suspect that had we designed a 
snitch in 12, we still would have faced uncomfortable evolutionary challenges 
now.  (For the record: I am still convinced that reform, rather than 
replacement, is the right move.)  

We knew the cost would be some asymmetries and some uncomfortable special cases 
(such as the current quarantining of preemptive null-hostility to the three 
legacy reference target types, enums/strings/boxes.)  But these costs are still 
far lower (IMO) than having two almost-the-same-but-not constructs living 
side-by-side forever, a burning hulk by the side of the road that is never 
extinguished.  At some level, the current discussion is an exploration of how 
much of our cake we can have and eat as well. 

When we did expressions switches, we knew the totality asymmetry was not a 
solved problem.  For the limited sorts of non-strongly-total switches we had 
then (just enum switches), doing nothing at the time, and keeping the option to 
do something later, was the obvious and right move.  As switches get more 
powerful, there are more kinds of non-strongly-total switches (switches over 
sealed types, switches with deconstruction patterns lifted over total pattern 
groups, etc), and the desire for some extra type checking (and automated 
remainder handling) becomes greater.  

For the current round (type patterns in switch), I think its probably practical 
to still do nothing now; I think the real need comes around when we get to 
deconstruction and nested patterns.  But none of the options discussed are 
perishable; the things that are compatible now will be compatible later, and 
the things that are incompatible now will still be incompatible later.  

> I just want to interject that I really dislike the terminology (and therefore 
> the syntax) “sealed switch” because it is too likely to confuse Joe 
> Programmer (or me) into thinking that it necessarily makes use of, or is used 
> in conjunction with, a sealed type.  One might also misconstrue it to mean 
> that the set of switch labels is fixed and cannot be added to later!

I agree that the reuse of “sealed” here is in the clever-possibly-too-clever 
category, and am happy to keep searching for something better.  I’ll just 
reiterate that there is a nice accidental connection to sealed-ness — that such 
switches are not “leaky”.  Sealing a switch means that there will be no values 
that are passed through and not acted upon.  

I bring this up again not to defend the syntax, but to underscore a more 
important point: that we thought at first that “sealing” switches was about 
asserting totality and enlisting the compiler’s aid in verifying same, but as 
we worked through the cases, and discovered there were more cases of remainder 
than we initially thought, the main value of sealing instead became restoring 
the switch to having no unhandled remainder.  Whatever syntax we choose should 
try to evoke that at least as much as evoking totality of the case labels.  


> On Sep 3, 2020, at 10:24 PM, Guy Steele <[email protected]> wrote:
> 
> There is currently a fundamental unpleasant asymmetry caused by the arbitrary 
> decision to require that all switch expressions be total but not all switch 
> statements be total.
> 
> As we have added other options, the design space still has an unpleasant 
> asymmetry (or lack of orthogonality) because of that original decision.
> 
> We have two choices: (a) recant that original decision, or (b) live with the 
> asymmetry.
> 
> As I have already pointed out, (a) is certainly possible and completely 
> consistent; all you have to do is return default values for the cases that 
> are not covered.  Then the choice of switch-versus-expression is completely 
> independent of the choice of regular-switch versus total-switch.  The likely 
> result is that authors and IDEs will warn programmers that they should NEVER 
> EVER use a non-total switch expression, so it seems silly to expand the 
> design space to provide a combination of features that should never be used.  
> (“What, never?”  “Well, hardly ever.”)
> 
> The other choice, which is what Rémi and Brian have been discussing for the 
> last week, is not whether to get rid of the asymmetry, but merely debating 
> exactly what its shape should be.
> 
> A possibility I don;’t think I have yet seen offered is that we should, as 
> before, require switch expressions to be total, but also, in an incompatible 
> move, require switch expressions to use whatever `total-switch` syntax is 
> adopted.
> 
> In such a scenario, perhaps we really are trying to move the world to 
> `snitch` after all, and we’re just arguing about the least disruptive 
> spelling for it.
> 
> —Guy
> 

Reply via email to