<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><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;"><b>From: </b>"Brian Goetz" <brian.goetz@oracle.com><br><b>To: </b>"Remi Forax" <forax@univ-mlv.fr>, "Viktor Klang" <viktor.klang@oracle.com><br><b>Cc: </b>"amber-spec-experts" <amber-spec-experts@openjdk.java.net><br><b>Sent: </b>Sunday, January 18, 2026 2:00:19 AM<br><b>Subject: </b>Re: Data Oriented Programming, Beyond Records<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><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;"><font size="4" face="monospace">In reality, the deconstructor is not
      a method at all.  <br><br>
      When we match:<br><br>
          x instanceof R(P, Q)<br><br>
      we first ask `instanceof R`, and if that succeeds, we call the
      accessors for the first two components.  The accessors are
      instance methods, but the deconstructor is not embodied as a
      method.  This is true for carriers as well as for records.</font></blockquote><div><br></div><div>Pattern matching and late binding are dual only for public types,</div><div>if an implementation class (the one containing the fields) is not visible from outside, the way to get to fields is by using late binding.</div><div><br data-mce-bogus="1"></div><div>If the only way to do the late binding is by using accessors, then you can not guarantee the atomicity of the deconstruction,</div><div>or said differently the pattern matching will be able to see states that does not exist.</div><div><br data-mce-bogus="1"></div><div>Let say I have a public thread safe class containing two fields, and I want see that class has a carrier class,</div><div>with the idea that a carrier class either provide a deconstructor method or accessors.</div><div>I can write the following code :</div><div><br data-mce-bogus="1"></div><div>  public final class ThreadSafeData(String name, int age) {</div><div>    private String name;</div><div>    private int age;</div><div>    private final Object lock = new Object();</div><div><br data-mce-bogus="1"></div><div>    public ThreadSafeData(String name, int age)  {</div><div>     synchronized(lock) {<div>        this.name = name;</div><div>        this.age = age;</div><div>      } </div></div><div>    }</div><div><br data-mce-bogus="1"></div><div>    public void set(String name, int age) {</div><div>      synchronized(lock) {</div><div>        this.name = name;</div><div>        this.age = age;</div><div>      }</div><div>    }<br><br></div><div><div>    public String toString() {</div><div>      synchronized(lock) {</div><div>         return name + " " + age;</div><div>      }</div><div>    }</div></div><div><br data-mce-bogus="1"></div><div>    public deconstructor() {. // no return type, the compiler checks that the return values have the same carrier definition</div><div>      record Tuple(String name, int age) { }</div><div>      synchronized(lock) {</div><div>        return new Tuple(name, age);</div><div>      }</div><div>    }</div><div><br data-mce-bogus="1"></div><div>    // no accessors here, if you want to have access the state, use pattern matching like this</div><div>    //  ThreadSafeHolder holder = ...</div><div>    //  ThreadSafeHolder(String name, int age) = holder;</div><div>  }</div><div>  </div><div>I understand that you are trying to drastically simplify the pattern matching model (yai !) by removing the deconstructor method but by doing that you are making thread safe classes second class citizens. </div><div> </div><div>regards,</div><div>Rémi</div><div><br data-mce-bogus="1"></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;"><font size="4" face="monospace"><br></font><br>
    <div class="moz-cite-prefix">On 1/17/2026 5:09 PM, <a class="moz-txt-link-abbreviated" href="mailto:forax@univ-mlv.fr" target="_blank">forax@univ-mlv.fr</a>
      wrote:<br>
    </div>
    <blockquote cite="mid:1864311863.19305629.1768687793277.JavaMail.zimbra@univ-eiffel.fr">
      
      <div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000">
        <div><br>
        </div>
        <div><br>
        </div>
        <hr id="zwchr">
        <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;"><b>From:
            </b>"Viktor Klang" <a class="moz-txt-link-rfc2396E" href="mailto:viktor.klang@oracle.com" target="_blank"><viktor.klang@oracle.com></a><br>
            <b>To: </b>"Remi Forax" <a class="moz-txt-link-rfc2396E" href="mailto:forax@univ-mlv.fr" target="_blank"><forax@univ-mlv.fr></a>, "Brian
            Goetz" <a class="moz-txt-link-rfc2396E" href="mailto:brian.goetz@oracle.com" target="_blank"><brian.goetz@oracle.com></a><br>
            <b>Cc: </b>"amber-spec-experts"
            <a class="moz-txt-link-rfc2396E" href="mailto:amber-spec-experts@openjdk.java.net" target="_blank"><amber-spec-experts@openjdk.java.net></a><br>
            <b>Sent: </b>Saturday, January 17, 2026 5:00:41 PM<br>
            <b>Subject: </b>Re: Data Oriented Programming, Beyond
            Records<br>
          </blockquote>
        </div>
        <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;">
            <p>Just a quick note regarding the following, given my
              experience in this area:</p>
            <div class="moz-cite-prefix">On 2026-01-17 11:36, Remi Forax
              wrote:<br>
            </div>
            <blockquote cite="mid:1085557496.17567763.1768646213005.JavaMail.zimbra@univ-eiffel.fr">A
              de-constructor becomes an instance method that must return
              a carrier class/carrier interface, a type that has the
              information to be destructured and the structure has to
              match the one defined by the type.</blockquote>
          </blockquote>
          <div><br>
          </div>
          <div>Hello Viktor,</div>
          <div>thanks to bring back that point,</div>
          <div><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;">
            This simply <b>does not work</b> as a deconstructor cannot
            be an instance-method just like a constructor cannot be an
            instance method: It strictly belongs to the type itself (not
            the hierarchy) and</blockquote>
          <div><br>
          </div>
          <div>It can work as you said for a concrete type, but for an
            abstract type, you need to go from the abstract definition
            to the concrete one,</div>
          <div>if you do not want to re-invent the wheel here, the
            deconstructor has to be an abstract instance method.</div>
          <div><br>
          </div>
          <div>For example, with a non-public named implementation</div>
          <div><br>
          </div>
          <div>interface Pair<F, S>(F first, S second) {</div>
          <div>  public <F,S> Pair<F,S> of(F first, S
            second) {</div>
          <div>    record Impl<F, S>(F first, S second) implements
            Pair<F, S>{ }</div>
          <div>    return new Impl<>(first, second);</div>
          <div>  }</div>
          <div>}</div>
          <div><br>
          </div>
          <div>inside Pair, there is no concrete field first and second,
            so you need a way to extract them from the implementation.</div>
          <div><br>
          </div>
          <div>This can be implemented either using accessors (first()
            and second()) but you have a problem if you want your
            implementation to be mutable and synchronized on a lock
            (because the instance can be changed in between the call to
            first() and the call to second()) or you can have one
            abstract method, the deconstructor.</div>
          <div><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;">
            it doesn't play well with implementing multiple interfaces
            (name clashing), and interacts poorly with overload
            resolution (instead of choosing most-specific, you need to
            select a specific point in the hierarchy to call the
            method). </blockquote>
          <div><br>
          </div>
          <div>It depends on the compiler translation, but if you limit
            yourself to one destructor per class (the dual of the
            canonical constructor), the deconstructor can be desugared
            to one instance method that takes nothing and return
            java.lang.Object, so no name clash and no problem of
            overloading (because overloading is not allowed, you have to
            use '_' at use site).</div>
          <div><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;">
            <pre class="moz-signature">-- 
Cheers,
√</pre>
          </blockquote>
          <div><br>
          </div>
          <div>regards,</div>
          <div>Rémi</div>
          <div><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;">
            <pre class="moz-signature">Viktor Klang
Software Architect, Java Platform Group
Oracle</pre>
            <br>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br><br></blockquote></div></div></body></html>