[External] : Re: Remainder in pattern matching

Brian Goetz brian.goetz at oracle.com
Wed Mar 30 16:32:15 UTC 2022

> For when the static world and the dynamic world disagree, i think your 
> analysis has miss an important question, switching on an enum throw an 
> ICCE very late when we discover an unknown value, but in the case of a 
> sealed type,

Actually, I thought about that quite a bit before proposing this. And my 
conclusion is: using ICCE was mostly a (well intentioned) mistake here, 
and "doubling down" on that path is more trouble than it is worth.  So 
we are minimally consistent with the ICCE choice in the cases that were 
compilable in 12, but for anything else, we follow the general rule.

The thought experiment that I did was: what if we had not done switch 
expressions in 12.  Then the only precedent we have to deal with is the 
null case, which has a pretty obvious answer.  So what would we do?  
Would we introduce 10s of catch-all cases solely for the purpose of 
diagnosing the source of remainder, or would we introduce a throwing 
default that throws MatchException on everything but null?  I concluded 
we would do the latter, so what is proposed here is basically that, but 
carving out the 12-compatibility case.

> Remainders are dangling else in a cascade of if ... else, so yes, we 
> have to care of them.

Yes, but we can care for all of them in one swoop with a synthetic default.

> So yes, it may a lot of bytecodes if we choose to add all branches but 
> the benefit is not questionable, it's far better than the alternative 
> which is GoodLuckFigureByYourselfException.

Yes, when you get a dynamic error here in a complex switch, the range of 
what could have gone wrong is large.  (The same will be true outside of 
switches when we have more kinds of patterns (list patterns, map 
patterns, etc) and more ways to compose patterns into bigger patterns; 
if we have a big complex pattern that matches the JSON document with the 
keys we want, if it doesn't match because (say) some integer nested nine 
levels deep overflowed 32 bits, this is also going to be hard to 
diagnose.)  But you are proposing a new and significant language 
requirement -- that the language should mandate an arbitrarily complex 
explanation of why something didn't match.  I won't dispute that this 
has benefit -- but I am not convinced this is necessarily the place for 
this, or whether the cost is justified by the benefit.

Also, note that the two are not inconsistent.  If the switch is required 
to throw MatchException on remainder, the compiler is *allowed* to try 
and diagnose the root cause (the ME can wrap something more specific), 
but not required to.   Pattern failure diagnosis then becomes a quality 
of implementation choice, rather than having complex, brittle rules 
mandated by the spec.  There's nothing to stop us from doing the 
equivalent of the "helpful NPE" JEP in the future.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20220330/7ad04770/attachment-0001.htm>

More information about the amber-spec-experts mailing list