Nullable switch

forax at univ-mlv.fr forax at univ-mlv.fr
Sat Aug 8 21:37:02 UTC 2020


----- Mail original -----
> De: "John Rose" <john.r.rose at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Vendredi 7 Août 2020 20:44:56
> Objet: Re: Nullable switch

> On Aug 6, 2020, at 4:22 PM, forax at univ-mlv.fr wrote:
>> 
>> people are not compilers,
> 
> People do model compilers, and as Brian has shown, there is
> already a workable concept (which Java programmers must
> model) about totality.
> 
>> because you are mixing totality and nullability,
> 
> This is the “pick your poison” moment:  Often, cleanly factoring
> out separate notations for separate concepts is the best move.
> 
> Not in this case.  The use cases (for totality and for null tolerance)
> are very strongly correlated after (a process that takes months in
> which) you run through all the various use cases and desired
> symmetries and other principles that Brian alludes to.

I'm always worry about this kind of sentence because of the sunk cost fallacy.


> It’s better to mix here; using separate “unmixed" notations leads to two
> strongly correlated channels of information that the poor
> programmer will have to manage in tandem, even in cases
> (common as Brian shows) where null policy isn’t even on the
> user’s mental radar. *That’s* requiring the user to do the
> compiler’s job.  Amber is about reducing ceremony; having
> too many notations to make the same choices, and requiring
> *both at the same time* is increasing ceremony.

I'm not against reducing the ceremony (obviously) and i understand that trying to guess what the user want can be appealing,
but using the fact that the case is total as a bit of information about what the user think supposes that the user knows the rules while
usually it's the opposite, the compiler enforces the rule.

Moreover, having a case being total is not a local property it depends on the type hierarchy which can be outside the compilation unit and as Jens Lideström also noticed, also depends on the type of the expression switched upon wihc can be hidden, combined with the fact that a switch statement doesn't have to cover all cases because of backward compatibility, it's a recipe for disaster.

> 
>> is the "case Comparable<?> c" accept null or not in the following code
>> is not an easy question
> 
> But as Brian showed, it is the sort of question that programmers
> have to be aware of:  Totality, like the DA/DU rules, is a concept
> they need to know about to program correctly.

Thanks for mentioning DA/DU rules, it helps me to refine why using the fact that the case is total or not is a bad idea.
- DA/DU rules are fully local, they don't rely on out of the compilation unit informations.
- DA/DU rules either allows an expression or reject it, here, in case of switch statement, if you guess wrong and the case is not total, you get another semantics (NPE or not) instead of compile or don't.

> 
> But the programmer doesn’t need to “be a compiler”; of course
> the compiler does the detail work and tells the programmer
> whether a given construct will fly or not.  And the programmer
> learns by pattern matching, hunches, intuitions, which sorts
> of statements and idioms are safe and which require greater
> scrutiny.  If you look at the examples and use cases, and/or
> try out some coding, I think you’ll find (as I did) that, because
> the total patterns in a switch are *forced* by the compiler
> to fall to the bottom, it’s *easy* to see at a glance which cases
> are null-tolerant and which are null-hostile.

Unfortunately, being at the bottom say nothing about the fact that the case is total or not.
It works in the opposite direction, a total case has to be at the bottom.

I think Brian and you have forgotten at some point the fact that a switch is in most cases defined in a different compilations unit/packages than the type it works on.
So having the last case being total at some point and later not being total because a file has changed somewhere, basically a separate compilation issue will be far more frequent than with the other constructs we usually deal with. So chagning the semantics of the last case (and the switch) depending on information we know may be not in sync is dangerous.

In a sense, using the case being total or not is a clever trick, not a smart one.

> 
> HTH
> 
> — John

Rémi


More information about the amber-spec-experts mailing list