Named record pattern
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue May 31 17:41:21 UTC 2022
While merging is an issue (if supported), I think early in the design we
settled on the principle that a binding variable should always only have
/one/ corresponding declaration (in the places where it is defined).
So, from a language perspective, I don’t see an immediate problem, in
the sense that the annotations and finality for “s” would come from the
place where “s” has been declared.
From a compiler perspective, the big question is whether, even in the
absence of merging in the flow scoping rules, we could still perform
merging under the hood, in order to speed up computation. Consider:
|sealed interface Node record Pair(Node fst, Node snd) { } record
A(String s) implements Node {} record B(int i) implements Node {} |
And then:
|case Pair(A(String s1), A(String s2)) -> ... case Pair(A(String s3),
B(int i1)) -> ... case Pair(B(int i2), A(String s4)) -> ... case
Pair(B(int i3), B(int i4)) -> ... |
(for simplicity, all binding names are different, so that we do not
depend on whether the block after -> … completes normally or not)
Of course the first two patterns share the common subpattern |A(String
s1)| (if you ignore naming differences). So it /might/ be possible, in
principle, for the compiler/runtime to generate an optimized decision
tree in which the String value for the first A(…) sub-pattern is
computed only once, and then shared in the two cases. (A similar
reasoning applies to the last two patterns).
But if the types in the first and second pattern could be annotated
differently, then we are faced with a number of challenges, as the
compiler would not be able to just “blindly” reuse the cached values (as
those values would be shared, and, therefore, unannotated). Instead, the
compiler would have to assign the cached value into a /fresh/, correctly
annotated local variable that is used only inside the given |case|. This
is not impossible of course, but adds complexity to the translation
strategy, and/or might affect the number of moves we might be able to do.
Maurizio
On 31/05/2022 17:12, Brian Goetz wrote:
> As a confounding example that suggests that pattern variables are not
> "just locals", in the past we talked about various forms of "merging":
>
> if (t instanceof Box(String s) || t instanceof Bag(String s)) { ... }
>
> or
>
> case Box(String s):
> case Bag(String s):
> common-code;
>
> If pattern variables could be annotated, then the language would be in
> the position of deciding what happens with
>
> case Box(@Foo(1) String s):
> case Bag(@Foo(2) String s):
>
> (This is the "annotation merging" problem, which is why annotations
> are not inherited in the first place.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20220531/bf7811ec/attachment.htm>
More information about the amber-spec-experts
mailing list