----- Original Message ----- > From: "Dan Heidinga" <heidi...@redhat.com> > To: "Brian Goetz" <brian.go...@oracle.com> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Sent: Wednesday, March 30, 2022 8:43:42 PM > Subject: Re: [External] : Re: Remainder in pattern matching
> On Wed, Mar 30, 2022 at 2:38 PM Brian Goetz <brian.go...@oracle.com> wrote: >> [...] > > And from your other response: > >> Another thing it gains is that it discourages people >> from thinking they can use exceptions in dtors; having these laundered >> through MatchException discourages using this as a side channel, though >> that's a more minor thing. > > This is a stronger argument than you give it credit for being. > Wrapping the exception adds a bit of friction to doing the wrong thing > which will pay off in helping guide users to the intended behaviour. Wrapping exceptions into a MatchException seems a very bad idea to me. When you compute something on an AST, the pattern matching is recursive, so if an exception occurs, instead of having one exception with a long stacktrace, we will get a linked list of MatchException with each of them having a long stacktraces. > > --Dan Rémi > >> On 3/30/2022 2:12 PM, Dan Heidinga wrote: >> >> The rules regarding NPE, ICCE and MatchException look reasonable to me. >> >> >> As a separate but not-separate exception problem, we have to deal with at >> least >> two additional sources of exceptions: >> >> - A dtor / record acessor may throw an arbitrary exception in the course of >> evaluating whether a case matches. >> >> - User code in the switch may throw an arbitrary exception. >> >> For the latter, this has always been handled by having the switch terminate >> abruptly with the same exception, and we should continue to do this. >> >> For the former, we surely do not want to swallow this exception (such an >> exception indicates a bug). The choices here are to treat this the same way >> we >> do with user code, throwing it out of the switch, or to wrap with >> MatchException. >> >> I prefer the latter -- wrapping with MatchException -- because the exception >> is >> thrown from synthetic code between the user code and the ultimate thrower, >> which means the pattern matching feature is mediating access to the thrower. >> I >> think we should handle this as "if a pattern invoked from pattern matching >> completes abruptly by throwing X, pattern matching completes abruptly with >> MatchException", because the specific X is not a detail we want the user to >> bind to. (We don't want them to bind to anything, but if they do, we want >> them >> to bind to the logical action, not the implementation details.) >> >> My intuition (and maybe I have the wrong mental model?) is that the >> pattern matching calling a user written dtor / record accessor is akin >> to calling a method. We don't wrap the exceptions thrown by methods >> apart from some very narrow cases (ie: reflection), and I thought part >> of reflection's behaviour was related to needing to ensure exceptions >> (particularly checked ones) were converted to something explicitly >> handled by the caller. >> >> If the dtor / record accessor can declare they throw checked >> exceptions, then I can kind of see the rationale for wrapping them. >> Otherwise, it seems clearer to me to let them be thrown without >> wrapping. >> >> I don't think we expect users to explicitly handle MatchException when >> using pattern matching so what does wrapping gain us here? >> >> --Dan >>