Named record pattern

Maurizio Cimadamore maurizio.cimadamore at
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.


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: <>

More information about the amber-spec-experts mailing list