<div dir="auto">Hi!<br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Wed, Jan 14, 2026, 20:50  <<a href="mailto:forax@univ-mlv.fr" target="_blank" rel="noreferrer">forax@univ-mlv.fr</a>> wrote</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:#000000" dir="auto"><div><div>Is it different from</div><div>  var a = foo().bar().getA();</div><div>  var b = foo().bar().getB();</div><div><br></div><div>which works like a charm in IntelliJ.</div></div></div></blockquote></div><div dir="auto"><br></div><div dir="auto">Here, if you search for getA invocation, you can query the identifier index for 'getA', which is mentioned. If you want to search for the type of a, then this location will not be found, because the type is not mentioned. Find usages is crucial for refactorings. If you rename the type, you don't need to find this location, because the type is not mentioned. However, if you reorder record components, you have to find all the deconstructions to update them as well, even if the record is not mentioned. Similarly, if you change the signature of functional interface SAM, you have to update all the lambdas, so you have to find them.</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><br></div><div class="gmail_quote" dir="auto"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:#000000" dir="auto"><div dir="auto"><br></div><div dir="auto">That said, I curently do not use 'var' in record patterns because IDEs (not IntelliJ) tend to miss those type references.</div><div dir="auto"><br></div><div dir="auto">In IntelliJ, you can add a lambda symbol in the gutter part of the editor, it will give you the functional interface.</div></div></blockquote></div><div dir="auto"><br></div><div dir="auto">Going from lambda to its functional interface is much simpler than the opposite task of finding all the lambdas in the project that implement this interface. While it's still a nontrivial type inference problem, it should be performed at a single location, not at thousands of possible locations all over the project.</div><div dir="auto"><br></div><div class="gmail_quote" dir="auto"></div><div class="gmail_quote" dir="auto"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:#000000" dir="auto"><div dir="auto"><br></div><div dir="auto">So yes, relying on type inference makes compilers slower and the IDEs slower, and reconciling indexes is a PITA,</div><div dir="auto">but suppressing redundant information in the code, for example<br>  (var x, var y) = foo.getPoint();<br><br></div><div dir="auto">also helps readability (see <a href="https://openjdk.org/projects/amber/guides/lvti-style-guide" rel="noreferrer noreferrer" target="_blank">https://openjdk.org/projects/amber/guides/lvti-style-guide</a>)</div><div dir="auto"><br></div><blockquote style="border-left:2px solid #1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><div dir="auto"><div><div dir="auto"><br></div><div dir="auto">With best regards, </div><div dir="auto">Tagir Valeev </div></div></div></blockquote><div dir="auto"><br></div><div dir="auto">regards,</div><div dir="auto">Rémi</div><div dir="auto"><br></div><blockquote style="border-left:2px solid #1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><div dir="auto"><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jan 14, 2026, 19:17 Remi Forax <<a href="mailto:forax@univ-mlv.fr" rel="noreferrer noreferrer" target="_blank">forax@univ-mlv.fr</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">----- Original Message -----<br>
> From: "Gavin Bierman" <<a href="mailto:gavin.bierman@oracle.com" rel="noreferrer noreferrer noreferrer" target="_blank">gavin.bierman@oracle.com</a>><br>
> To: "amber-spec-experts" <<a href="mailto:amber-spec-experts@openjdk.java.net" rel="noreferrer noreferrer noreferrer" target="_blank">amber-spec-experts@openjdk.java.net</a>><br>
> Sent: Saturday, January 10, 2026 12:08:05 AM<br>
> Subject: Amber features 2026<br>
<br>
> Dear spec experts,<br>
> <br>
> Happy New Year to you all! We thought this was a good time to share you some of<br>
> the thinking regarding Amber features for 2026.<br>
> <br>
> Currently we have one feature in preview - Primitive Patterns. We’d love to get<br>
> more feedback on this feature - please keep kicking the tires!<br>
> <br>
> We plan two new features in the near term. Draft JEPs are being worked on and<br>
> will be released as soon as possible. But here are some brief details while you<br>
> are waiting for the draft JEPs (in the name of efficiency, *please* let's save<br>
> discussion for that point).<br>
> <br>
> ## PATTERN ASSIGNMENT<br>
> <br>
> Pattern matching is an inherently partial process: a value either matches a<br>
> pattern, or it does not. But sometimes, we know that the pattern will always<br>
> match; and we are using the pattern matching process as a convenient means to<br>
> disassemble a value, for example:<br>
> <br>
>    record ColorPoint(int x, int y, RGB color) {}<br>
>    <br>
>    void somethingImportant(ColorPoint cp) {<br>
>        if (cp instanceof ColorPoint(var x, var y, var c)) {<br>
>            // important code<br>
>        }<br>
>    }<br>
> <br>
> The use of pattern matching is great, but the fact that we have to use it in a<br>
> conditional statement is annoying. It’s clutter, and worse, it is making<br>
> something known by the developer and compiler look as if it were unknown; and,<br>
> as a consequence, the important code ends up being indented and the scope of<br>
> the pattern variables is limited to the then block. The indent-adverse<br>
> developer may reach for the following, but it’s hardly better:<br>
> <br>
>    void somethingImportant(ColorPoint cp) {<br>
>        if (!(cp instanceof ColorPoint(var x, var y, var c))) {<br>
>            return;<br>
>        }<br>
>        // important code<br>
>    }<br>
> <br>
> The real issue here is that both the developer and the compiler can see that the<br>
> pattern matching is not partial - it will always succeed - but we have no way<br>
> of recording this semantic information.<br>
> <br>
> What we really want is a form of assignment where the left-hand-side is not a<br>
> variable but a **pattern**. So, we can rewrite our method as follows:<br>
> <br>
>    void somethingImportant(ColorPoint cp) {<br>
>        ColorPoint(var x, var y, var c) = cp;    // Pattern Assignment!<br>
>        // important code<br>
>    }<br>
> <br>
> Luckily, the spec already defines what it means for a pattern to be<br>
> unconditional (JLS 14.30.3), so we can build on this<br>
> <br>
>    void hopeful(Object o) {<br>
>        ColorPoint(var x, var y, var c) = o; // Compile-time error!<br>
>    }<br>
> <br>
> <br>
<br>
Doing the advent of code of last December, I miss that feature :)<br>
<br>
But I'm still ambivalent about that feature, for me, it looks like we are missing the big picture.<br>
<br>
<br>
Every time i've talked about this feature in JUGs, one of the questions was why do we need to indicate the type given that the compiler knows it.<br>
For example<br>
<br>
  void hopeful(ColorPoint cp) {<br>
    (var x, var y, var c) = cp;<br>
<br>
    // instead of<br>
<br>
    ColorPoint(var x, var y, var c) = cp;<br>
  }<br>
<br>
<br>
I wonder if the general question hidden behind is why is it a pattern assignment and not a de-structuration like in other languages.<br>
<br>
Let's take another example, in other languages, one can write swap like this<br>
  int a = ...<br>
  int b = ...<br>
  (b, a) = (a, b);<br>
<br>
The equivalent would be<br>
<br>
  record Pair(int first, int second) {}<br>
  int a = ...<br>
  int b = ...<br>
  Pair(var x, var y) = new Pair(a, b);<br>
  a = x;<br>
  b = y;<br>
<br>
Or should we support assignment without the creation of new bindings ?<br>
<br>
  record Pair(int first, int second) {}<br>
  int a = ...<br>
  int b = ...<br>
  Pair(b, a) = new Pair(a, b);<br>
<br>
Or maybe, this feature should be named pattern declaration and not pattern assignment ?<br>
<br>
<br>
For me, this feature is about de-structuring assignment but by seeing through the keyhole of patterns, i'm fearing we are missing the big picture here.<br>
<br>
regards,<br>
Rémi<br>
</blockquote></div></div></div><br></blockquote></div></blockquote></div></div>