> From: "Brian Goetz" <brian.go...@oracle.com> > To: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Sent: Friday, April 22, 2022 3:34:29 PM > Subject: Re: [External] : Re: Record pattern and side effects
>>> Let's imagine that dtor D throws. The wrapping happens when a dtor/accessor >>> is >>> invoked _implicitly_ as a result of evaluating a pattern match. In both >>> cases, >>> we will wrap the thrown exception and throw MatchException. In this way, >>> both >>> instanceof and switch are "clients of" pattern matching, and it is pattern >>> matching that throws. >>> I don't see any destruction here. >> I'm thinking about the refactoring from a code using accessors to a code >> using a >> deconstructor. >> By example, IDEs may propose to refactor this code >> if (x instanceof D d) A(d.p()); else B; >> to >> if (x instanceof D(P p)) A(p); else B; >> or vice versa >> If you wraps deconstructor exceptions, but not accessor exceptions you have >> mismatch. > OK, sure. This bothers me zero. Having an accessor (or dtor) throw is already > really^3 weird; having a program depend on which specific exception it throws > is really^32 weird. (In both cases, they still throw an exception that you > probably shouldn't be catching, with a clear stack trace explaining where it > went wrong.) Not a case to design the language around. > Still not seeing any "destruction" here. Let's try with a puzzler, i have a recursive list with a slight twist, the Cons can store the size of the list or not (using -1 if not). The accessor throws an exception and with the semantics you propose it will happily be wrapped by as many MatchExceptions as possible. public sealed interface RecChain { default int size() { return switch (this) { case Nil __ -> 0; case Cons(var v, var s, var next) -> 1 + next.size(); }; } record Nil() implements RecChain { } record Cons(int value, int size, RecChain next) implements RecChain { @Override public int size() { return size != -1? size: RecChain.super.size(); } } public static void main(String[] args){ RecChain chain = new Nil(); for (var i = 0; i < 100; i++) { chain = new Cons(i, -1, chain); } System.out.println(chain.size()); } } Rémi