> From: "Brian Goetz" <brian.go...@oracle.com> > To: "Tagir Valeev" <amae...@gmail.com> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Sent: Tuesday, May 31, 2022 6:12:06 PM > Subject: Re: Named record pattern
> Gavin reminded me that we are not finalizing patterns in switch in 19 (hard to > keep track, sometimes), so we have a little bit of time to figure out what we > want here. > One thing that is potentially confusing is that patterns work indirectly in a > number of ways. For example, if we have a declared deconstruction pattern for > Point, you can't *invoke* it as you can a method; the language runtime invokes > it on your behalf under the right situations. (In this way, a deconstructor is > a little like a static initializer; it is a body of code that you declare, but > you can't invoke it directly, the runtime invokes it for you at the right > time, > and that's fine.) > I had always imagined the relationship with locals being similar; a pattern > causes a local to be injected into certain scopes, but the pattern itself is > not a local variable declaration. Obviously there is more than one way to > interpret this, so we should make a more deliberate decision. > 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.) > I don't have an answer here, but I'm going to think about the various issues > and > try to capture them in more detail before proposing an answer. For me, there is a difference between a binding and a local variable, is that bindings are the one declared inside a pattern and a local variables is how a binding is transformed to be usable inside the boby if the pattern match. So we can merge bindings and as a result have one local variable to be used in the body. About the annotations, if we follow the data orientation principle (data is more important than code), we can have a record record Person(@NonNull String name) { } and a record pattern case Person(@NonNull String s) -> ... We want to be able to declare @NonNull in the record pattern so if the data is changed, if the component name of the record becomes nullable by example, the pattern will fail to compile. So i think we should allow annotations because it's a way to enforce that data are more important that code. As you said, annotation merging is an issue because the correct merging requires to know the semantics of the annotations and the compiler has no way to know that. But there is a simple solution, annotation are trees, so they can be compared structurally. Thus we can do bindings merging if the annotations are the same structurally. regards, RĂ©mi