> From: "Brian Goetz" <[email protected]>
> To: "amber-spec-experts" <[email protected]>
> 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