[External] : Re: Record pattern and side effects

forax at univ-mlv.fr forax at univ-mlv.fr
Fri May 6 09:05:15 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: 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 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20220506/2cd88d74/attachment.htm>


More information about the amber-spec-experts mailing list