[External] : Re: Declared patterns -- translation and reflection
Brian Goetz
brian.goetz at oracle.com
Wed Mar 30 00:40:46 UTC 2022
I am disappointed that you took this as an invitation to digress into
syntax here, when it should have been blindingly obvious that this was
not the time for a syntax discussion. (And when there is a syntax
discussion, which this isn't, we need to cover all the different forms
of declared patterns together; trying to design dtor patterns in a
vacuum misses a number of considerations.)
I'll respond to your other points separately.
On 3/29/2022 6:19 PM, Remi Forax wrote:
>
>
> ------------------------------------------------------------------------
>
> *From: *"Brian Goetz" <brian.goetz at oracle.com>
> *To: *"amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> *Sent: *Tuesday, March 29, 2022 11:01:18 PM
> *Subject: *Declared patterns -- translation and reflection
>
> Time to take a peek ahead at _declared patterns_. Declared
> patterns come in three varieties -- deconstruction patterns,
> static patterns, and instance patterns (corresponding to
> constructors, static methods, and instance methods.) I'm going to
> start with deconstruction patterns, but the basic game is the same
> for all three.
>
>
> I mostly agree with everything said apart from the syntax of a
> deconstructor
> (see my next message about how small things can be improved).
>
> I have several problems with the proposed syntax for a deconstructor.
> I can see the appeal of having a code very similar to a constructor
> but it's a trap, a constructor and a deconstructor do not have the
> same semantics, a constructor initialize fields (which have a name)
> while a deconstructor (or a pattern method) initialize bindings which
> does not have a name at that point yet.
>
> 1/ conceptually there is a mismatch, the syntax introduce names for
> the bindings, but they have no names at that point, bindings only have
> names AFTER the pattern matching succeed.
> 2/ sending the value of the binding by name is alien to Java. In Java,
> sending values is by the position of the value.
> 3/ the conceptual mismatch also exists at runtime, you need to permute
> the value of bindings before creating the carrier because a carrier
> takes the value of the binding by position while the code will takes
> the value of the bindings by name (you need the equivalent of
> MethodHandles.permuteArguments() otherwise you will see the
> re-organisation of the code if they are side effects).
>
> Let's try to come with a syntax,
> as i said, bindings have no names at that point so the deconstructor
> should declare the bindings (int, int) and not (int x, int y),
> so a syntax like
>
> _deconstructor_ (int, int) {
> _send_bindings_(this.x, this.y);
> }
>
> Here the syntax shows that the value of the bindings are assigned
> following the position of the expression like usual in Java.
>
>
> We can discuss if _send_bindings_ should be "return" or another
> keyword and if the binding types should be declared before or after
> _deconstructor_.
>
> By example, if you wan to maintain a kind of symmetry with the
> constructor, we can reuse the name of the class instead of
> _deconstructor_ and move the binding types in front of the name of the
> class to show that the bindings move from the class to the pattern
> matching in the same direction like a return type of a method.
> Something like this:
> (int, int) Point {
> _send_bindings_(this.x, this.y);
> }
>
> To summarize, the proposed syntax does the convey the underlying
> semantics of the bindings initialization and make things more
> confusing than it should.
>
>
>
> Ignoring the trivial details, a deconstruction pattern looks like
> a "constructor in reverse":
>
> ```{.java}
> class Point {
> int x, y;
>
> Point(int x, int y) {
> this.x = x;
> this.y = y;
> }
>
> deconstructor(int x, int y) {
> x = this.x;
> y = this.y;
> }
> }
> ```
>
>
> Rémi
>
More information about the amber-spec-observers
mailing list