[External] : Re: Remainder in pattern matching

forax at univ-mlv.fr forax at univ-mlv.fr
Wed Mar 30 18:31:34 UTC 2022


> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Sent: Wednesday, March 30, 2022 6:32:15 PM
> Subject: Re: [External] : Re: Remainder in pattern matching

>> 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.
We are discussing about what to do if a sealed types has more permitted subtypes at runtime than the one seen when the code was compiled. 
It's a separate compilation issue, hence the ICCE. 

It seems that what you are saying is that you think an Exception is better than an Error. 
If we follow that path, it means that it may make sense to recover from a MatchException but i fail to see how, we can not ask a developer of a code to change it while that code is executed, separate compilation errors are not recoverable. 

>> 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.
The explanation is not complex, there is a sealed type has more subtypes now than at a time the code was compiled. 

Rémi 


More information about the amber-spec-observers mailing list