Record pattern and side effects

forax at univ-mlv.fr forax at univ-mlv.fr
Thu Apr 21 09:28:45 UTC 2022


----- Original Message -----
> 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: Sunday, April 17, 2022 4:58:26 PM
> Subject: Re: Record pattern and side effects

> Yes, this is something we have to get “on the record”.
> 
> Record patterns are a special case of deconstruction patterns; in general, we
> will invoke the deconstructor (which is some sort of imperative code) as part
> of the match, which may have side-effects or throw exceptions.  With records,
> we go right to the accessors, but its the same game, so I’ll just say “invoke
> the deconstructor” to describe both.
> 
> While we can do what we can to discourage side-effects in deconstructors, they
> will happen.  This raises all sorts of questions about what flexibility the
> compiler has.
> 
> Q: if we have
> 
>    case Foo(Bar(String s)):
>    case Foo(Bar(Integer i)):
> 
> must we call the Foo and Bar deconstructors once, twice, or “dealer’s choice”?
> (I know you like the trick of factoring a common head, and this is a good
> trick, but it doesn’t answer the general question.)
> 
> Q: To illustrate the limitations of the “common head” trick, if we have
> 
>    case Foo(P, Bar(String s)):
>    case Foo(Q, Bar(String s)):
> 
> can we factor a common “tail”, where we invoke Foo and Bar just once, and then
> use P and Q against the first binding?
> 
> Q: What about reordering?  If we have disjoint patterns, can we reorder:
> 
>    case Foo(Bar x):
>    case TypeDisjointWithFoo t:
>    case Foo(Baz x):
> 
> into
> 
>    case Foo(Bar x):
>    case Foo(Baz x):
>    case TypeDisjointWithFoo t:
> 
> and then fold the head, so we only invoke the Foo dtor once?
> 
> Most of the papers about efficient pattern dispatch are relatively little help
> on this front, because the come with the assumption of purity /
> side-effect-freedom.  But it seems obvious that if we were trying to optimize
> dispatch, our cost model would be something like arithmetic op << type test <<
> dtor invocation, and so we’d want to optimize for minimizing dtor invocations
> where we can.

yes !

> 
> We’ve already asked one of the questions on side effects (though not sure we
> agreed on the answer): what if the dtor throws?  The working story is that the
> exception is wrapped in a MatchException.  (I know you don’t like this, but
> let’s not rehash the same arguments.)

Wrapping exceptions into a MatchException destroy any idea of refactoring from a cascade of if ... instanceof to a switch.

I think refactoring is a use case we should support.

Rémi


More information about the amber-spec-experts mailing list