[External] : Re: Remainder in pattern matching

Brian Goetz brian.goetz at oracle.com
Wed Mar 30 18:26:53 UTC 2022


It's a little like calling a method, but a little not like it too. For 
example, when you match on a record pattern:

     case Point(var x, var y): ...

what may happen is *either* you will invoke a user-written deconstructor 
pattern, *or* we will test if you are a Point with `instanceof`, and 
then invoke the accessor methods (which might be user-written or 
implicit.)  Similarly, if you match:

     case Point(P, Q):
     case Point(R, S):

we may invoke the Point deconstructor once, or twice.  And there's no 
way to _directly_ invoke a pattern, only through switch, instanceof, and 
other contexts.

All of this means that invocations of pattern methods is more indirect, 
and mediated by the language, than invoking a method. When you invoke a 
method, you are assenting to its contract about what it returns, what it 
throws, etc.  When you match a pattern, it feels more likely are 
assenting to the contract of _pattern matching_, which in turn hides 
implementation details of what pattern methods are invoked, when they 
are invoked, how often, etc.

Dtors and record accessors cannot throw checked exceptions at all, and 
will be discouraged from throwing exceptions at all.

One thing wrapping gains is that it gives us a place to centralize 
"something failed in pattern matching", which includes exhaustiveness 
failures as well as failures of invariants which PM assumes (e.g., dtors 
don't throw.)   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.

Agree we do not expect users to explicitly handle ME, any more so than NPE.

> 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
>



More information about the amber-spec-experts mailing list