> On Aug 20, 2020, at 6:14 PM, Brian Goetz <brian.go...@oracle.com> wrote:
> 
> I suspect there are other orderings too, such as "any nulls beat any novels" 
> or vice versa, which would also be deterministic and potentially more natural 
> to the user.  But before we go there, I want to make sure we have something 
> where users can understand the exceptions that are thrown without too much 
> head-scratching.  
> 
> If a user had:
> 
>     case Box(Head)
>     case Box(Tail)
> 
> and a Box(null) arrived unexpectedly at the switch, would NPE really be what 
> they expect?  An NPE happens when you _dereference_ a null.  But no one is 
> deferencing anything here; it's just that Box(null) fell into that middle 
> space of "well, you didn't really cover it, but it's such a silly case that I 
> didn't want to make you cover it either, but here we are and we have to do 
> something."  So maybe want some sort of SillyCaseException (perhaps with a 
> less silly name) for     at least the null residue.  

I believe that if Head and Tail exhaustively cover an enum or sealed type (as 
was the intended implication of my example)—more generally, in a situation that 
is optimistically total---then the user would be very happy to have some sort 
of error signaled if some other value shows up unexpectedly in a statement 
switch, whether that value is “Ankle" or “null”.  Maybe a new error name would 
be appropriate, such as UnexpectedNull.

If the user does not want such implicit handling of an optimistically total 
situation in a statement switch, then it is always possible to provide explicit 
clauses “case null: break;” and “default: break;”.

> On the other hand, ICCE for Box(novel) does seem reasonable because the world 
> really has changed in an incompatible way since the user wrote the code, and 
> they probably do want to be alerted to the fact that their code is out of 
> sync with the world. 

Yep.

> Separately (but not really separately), I'd like to refine my claim that 
> `switch` is null-hostile.  In reality, `switch` NPEs on null in three cases: 
> a null enum, String, or primitive box.  And, in each of these cases, it NPEs 
> because (the implementation) really does dereference the target!  For a 
> `String`, it calls `hashCode()`.  For an `enum`, it calls `ordinal()`.  And 
> for a box, it calls `xxxValue()`.  It is _those_ methods that NPE, not the 
> switch.  (Yes, we could have designed it so that the implementation did a 
> null check before calling those things.)  

Reply via email to