[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