Java 14 records canonical constructor
Brian Goetz
brian.goetz at oracle.com
Thu Jun 4 20:37:40 UTC 2020
> Let's say that normalization is allowed in the canonical constructor,
> how would that interact with e.g. pattern matching which I assume is
> the main consumer of the "re-construction" property of records.
Then the constructor ((int, int) -> R) and the deconstructor (R -> (int,
int)) form a _projection-embedding pair_, which have the property that
given:
record R r = ...
R rr = new R(r.c0(), r.c1(), ... r.cn())
then `rr.equals(r)`. In other words, the composed function $ctor \dot
dtor$ is an identity on R (but not necessarily the other way around.)
> Would the following match the first or the second case?
>
> switch (new Rational(1, 2)) {
> case Rational(2, 4):
> break;
> case Rational(1, 2):
> break;
> }
To ask `x instanceof Rational(2, 4)` (assuming numeric literals are the
denotation of constant patterns), this expression is equivalent to
matching the pattern:
Rational(var _a, var _b) && _a instanceof 2 && _b instanceof 4
I think there's your answer. The sub-patterns are not "passed" like
parameters to the deconstruction pattern; they stay at the use site, and
are applied monadically if the outer pattern matches. There is no
Rational that will match the pattern `Rational(2, 4)`.
> I guess what I am asking is, will the pattern cause a Rational object
> to be instantiated such that the normalization can happen for that
> pattern object as well? If not, then it seems to me that a canonical
> constructor that alters/mutates the arguments is broken and can't be
> used for pattern matching.
I think maybe you just have a mental model of how records and/or pattern
matching works, and it isn't quite how it does work. (That's fine, and
we're happy to educate, but loaded words like "broken" are probably best
avoided.)
Pattern matching is _destructuring_; taking a whole and destructuring it
into parts. The output of a pattern match on a rational is going to be
some flavor of "numerator and denominator".
I think what you're probably thinking is that asking `x instanceof
Rational(2, 4)` means "could x have come from the constructor invocation
`new Rational(2, 4)`. But that's not what it means. (Though you can ask
this question easily by: r.equals(new Rational(2,4))`.
More information about the amber-dev
mailing list