<head><!-- BaNnErBlUrFlE-HeAdEr-start -->
<style>
  #pfptBanner596t03u { all: revert !important; display: block !important;
    visibility: visible !important; opacity: 1 !important;
    background-color: #60beeb !important;
    max-width: none !important; max-height: none !important }
  .pfptPrimaryButton596t03u:hover, .pfptPrimaryButton596t03u:focus {
    background-color: #77a8c4 !important; }
  .pfptPrimaryButton596t03u:active {
    background-color: #8193a0 !important; }
  html:root, html:root>body { all: revert !important; display: block !important;
    visibility: visible !important; opacity: 1 !important; }
</style>

<!-- BaNnErBlUrFlE-HeAdEr-end -->
</head><!-- BaNnErBlUrFlE-BoDy-start -->
<!-- Preheader Text : BEGIN -->
<div style="display:none !important;display:none;visibility:hidden;mso-hide:all;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;opacity:0;overflow:hidden;">
I like the message here, it simple, and as you said we can built on it. """ A class with a state description means that it has accessors for each component, and has a canonical deconstruction pattern -- that's it "" One missing discussion is</div>
<!-- Preheader Text : END -->

<!-- Email Banner : BEGIN -->
<div style="display:none !important;display:none;visibility:hidden;mso-hide:all;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;opacity:0;overflow:hidden;">ZjQcmQRYFpfptBannerStart</div>

<!--[if ((ie)|(mso))]>
  <table border="0" cellspacing="0" cellpadding="0" width="100%" style="padding: 0px 0px 10px 0px; direction: ltr" lang="en"><tr><td>
    <table border="0" cellspacing="0" cellpadding="0" style="padding: 0px 8px 6px 8px; width: 100%; border-radius:4px; border-top:4px solid #8193a0;background-color:#60beeb;"><tr><td valign="top">
      <table align="left" border="0" cellspacing="0" cellpadding="0" style="padding: 0px 8px 4px 8px; font-size: 12px; line-height: 16px">
        <tr><td style="color:#000000; font-family: 'Arial', sans-serif; font-weight:bold; font-size:14px; line-height: 20px; direction: ltr">
          This Message Is From an External Sender
        </td></tr>
        <tr><td style="color:#000000; font-weight:normal; font-family: 'Arial', sans-serif; font-size:12px; direction: ltr">
          This message came from outside your organization.
        </td></tr>

      </table>
      <![if ie]><br clear="all"><![endif]>
      <table align="right" border="0" cellspacing="0" cellpadding="0" style="padding: 0px 0px 4px 0px; font-size: 14px; line-height: 36px"><tr>
        <td style="direction: ltr">  <a target="_blank" href="https://us-phishalarm-ewt.proofpoint.com/EWT/v1/ACWV5N9M2RV99hQ!Oj27dymuesjutVAjF1KU21qnLTyMSem_7iWLW8GBTSD9gNstUDYqRgbBG9NQ5HAeDTB1GPWpaxfifscqfMC1Znw_bdffRkxbd7uB8pKN0fohQofHMW1-X4-8Ro_YXmaliSExJlU$" style="mso-padding-alt: 7px; padding: 7px; border-radius: 2px; border: 1px solid #666666; "><strong style="font-weight: normal; color: #000000; text-decoration: none; font-family: 'Arial', sans-serif; font-size: 14px;">  Report Suspicious  </strong></a>  ‌ </td>
      </tr></table>
    </td></tr></table>
  </td></tr></table>
<![endif]-->

<![if !((ie)|(mso))]>
  <div dir="ltr" lang="en" id="pfptBanner596t03u" style="all: revert !important; display:block !important; text-align: left !important; margin: 0 0 10px 0 !important; padding:7px 16px 8px 16px !important; border-radius: 4px !important; min-width: 200px !important; background-color: #60beeb !important; background-color: #60beeb; border-top: 4px solid #8193a0 !important; border-top: 4px solid #8193a0;">
    <div id="pfptBanner596t03u" style="all: unset !important; float:left !important; display:block !important; margin: 1px 0 1px 0 !important; max-width: 600px !important;">
      <div id="pfptBanner596t03u" style="all: unset !important; display:block !important; visibility: visible !important; background-color: #60beeb !important; color:#000000 !important; color:#000000; font-family: 'Arial', sans-serif !important; font-family: 'Arial', sans-serif; font-weight:bold !important; font-weight:bold; font-size:14px !important; line-height:1.29 !important; line-height:1.29">
        This Message Is From an External Sender
      </div>
      <div id="pfptBanner596t03u" style="all: unset !important; display:block !important; visibility: visible !important; background-color: #60beeb !important; color:#000000 !important; color:#000000; font-weight:normal; font-family: 'Arial', sans-serif !important; font-family: 'Arial', sans-serif; font-size:12px !important; line-height:1.5 !important; line-height:1.5; margin-top:2px !important;">
This message came from outside your organization.
      </div>

    </div>
    <div id="pfptBanner596t03u" style="all: unset !important; float: right !important; display: block !important; display: block; margin-left: 16px !important; margin-top: 1px !important; text-align: right !important; width: fit-content !important; font-size: 12px !important">
<a id="pfptBanner596t03u" href="https://us-phishalarm-ewt.proofpoint.com/EWT/v1/ACWV5N9M2RV99hQ!Oj27dymuesjutVAjF1KU21qnLTyMSem_7iWLW8GBTSD9gNstUDYqRgbBG9NQ5HAeDTB1GPWpaxfifscqfMC1Znw_bdffRkxbd7uB8pKN0fohQofHMW1-X4-8Ro_YXmaliSExJlU$"
    style="all: unset !important; display: inline-block !important; text-decoration: none">
    <div class="pfptPrimaryButton596t03u" style="display: inline-block !important; display: inline-block; visibility: visible !important; opacity: 1 !important; color: #000000 !important; color: #000000; font-family: 'Arial', sans-serif !important; font-family: 'Arial', sans-serif; font-size: 14px !important;  font-weight: normal !important; text-decoration: none !important; border-radius: 2px !important; margin-top: 3px !important; margin-bottom: 3px !important; margin-left: 16px !important; padding: 7.5px 16px !important; white-space: nowrap !important; width: fit-content !important;
        border: 1px solid #666666">
        Report Suspicious
    </div>
</a>
    </div>
    <div style="clear: both !important; display: block !important; visibility: hidden !important; line-height: 0 !important; font-size: 0.01px !important; height: 0px"> </div>
  </div>
<![endif]>

<div style="display:none !important;display:none;visibility:hidden;mso-hide:all;font-size:1px;color:#ffffff;line-height:1px;max-height:0px;opacity:0;overflow:hidden;">ZjQcmQRYFpfptBannerEnd</div>
<!-- Email Banner : END -->

<!-- BaNnErBlUrFlE-BoDy-end -->
<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div>I like the message here,</div><div>it simple, and as you said we can built on it.</div><div><br data-mce-bogus="1"></div><div>"""</div><div><span style="font-family: monospace; font-size: large;">A class with a state description means that it has accessors for each <br>component, and has a canonical deconstruction pattern -- that's it</span></div><div><span style="font-family: monospace; font-size: large;">""</span></div><div><br data-mce-bogus="1"></div><div>One missing discussion is serialization or exatcly what about the easy serialization we get with records ?</div><div><br data-mce-bogus="1"></div><div>If a deconstructible class implement Serializable, should a canonical constructor, with the same visibility as the class, required * ?</div><div><br data-mce-bogus="1"></div><div>Sadly, it's not a decision we can postpone, because it's not a backward compatible change.</div><div><br data-mce-bogus="1"></div><div>So should we have a special case for Serializable classes ?</div><div><br data-mce-bogus="1"></div><div>regards,</div><div>Rémi</div><div><br data-mce-bogus="1"></div><div>* apart if there is a writeReplace or one of the other weird serializations mechanisms is present.</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>"amber-spec-experts" <amber-spec-experts@openjdk.java.net><br><b>Sent: </b>Wednesday, February 25, 2026 3:55:59 PM<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">We've had some good discussions
      here, and I've got some updates to the ideas outlined in the
      previous snapshot.  There's a lot here, including a lot that I'm
      identifying as likely future directions but which should not be
      the topic of current discussion; I want to focus on the
      highest-priority aspects first (even though some of the
      lower-priority aspects are surely going to be tempting to
      discuss.)<br>
      <br>
      As we saw with records, there are two forces operating here, which
      are to some degree in competition: <br>
      <br>
       - A desire for stronger semantics.  A class commits to almost
      nothing; a record commits to quite a lot -- by disavowing the
      freedom to do things that are outside the profile of "transparent,
      shallowly-immutable data carrier".  From these stronger semantics,
      we can derive features such as deconstructability (pattern
      matching), reconstructability (withers), etc, as well as deriving
      a number of usually-boilerplate class members.  <br>
      <br>
       - A desire for concise representation, not necessarily because of
      the effort of writing that code (IDEs will write it for you), but
      because _reading code that adds no value_ obfuscates intent.  (As
      always, reading code is more important than writing code.)<br>
      <br>
      With records, we managed to get these entirely aligned; we were
      able to derive the desirable concise representation entirely from
      having picked the right semantics; this is what winning looks
      like.  With the "carrier classes" suggestion as outlined in the
      previous snapshot, we are not quite there yet, and we've likely
      slid a little too far into the "unprincipled concision" camp, so
      we need to make some adjustments.  <br>
      <br>
      Additionally, there was something very uncomfortable about the
      "carrier classes" proposal; it was a lot harder to look at a class
      and tell whether the absence of explicit declarations of certain
      members (especially equals and hashCode) meant they didn't exist,
      or whether it meant they were derived.  The current situation
      where records get a lot of derived stuff and no one else does,
      while inconvenient for all non-record classes, has more clarity.  <br>
      <br>
      In this mail, I outline a slightly different, somewhat more
      principled position, that addresses these concerns.  Concision
      fans may be disappointed in some ways.  <br>
      <br>
      ## Sizing up the problem<br>
      <br>
      The strong semantic guarantee of records gives us:<br>
      <br>
       - API contracts<br>
         - construction protocol (canonical constructor)<br>
         - deconstruction protocol (record patterns)<br>
         - component access protocol (accessor methods)<br>
         - state-based equality / hashCode / toString<br>
       - Implementation convenience<br>
         - representation (fields)<br>
         - canonical constructor (modulo parameter validation and
      normalization)<br>
           - Option to use compact constructor form<br>
         - component accessors<br>
    </font><font size="4" face="monospace">   - record pattern (derived
      from accessors)<br>
         - implementations of equals, hashCode, toString<br>
       - Potential future semantic features<br>
         - reconstruction (withers)<br>
         - nominal construction and deconstruction<br>
    </font><font size="4" face="monospace"><br>
      It will not be possible to give all of these benefits to the
      almost-record classes, because some derive directly from giving up
      flexibility that almost-records don't want to give up, such as the
      ability to have an internal representation that differs from the
      external API.  In these cases, the implementation will have to
      "connect the dots" to some degree; our measure of progress will be
      the degree to which the required code is proportional to the
      deviation from the ideal.  <br>
      <br>
      To get there, we will take the approach of first solving a smaller
      but more coherent problem -- how we get to deconstruction for
      arbitrary classes and interfaces -- and then come back as needed
      with more targeted tools for chipping away at the declaration
      overhead.  <br>
      <br>
      ## Incomplete, canonical, nominal state descriptions<br>
      <br>
      In the previous round, we described the state description of a
      carrier class as a "complete, canonical, nominal state
      description" -- but this reflected a sort of wishful thinking. 
      What it really was was an _incomplete_, canonical, nominal state
      description!  Because we cannot not stop the user from declaring
      additional state that might affect core behavior -- and in fact,
      the whole point is to give the user more freedom in defining the
      representation.  <br>
      <br>
      Acknowledging this means we gain some clarity but lose some
      concision.  The gained clarity is that a state description on an
      interface or class means something narrower than initially claimed
      -- that this class has these specific named components, and that
      it can be deconstructed with a canonical deconstruction pattern,
      whose shape matches that of the state description.  The lost
      concision derives from lost semantics -- we really don't have a
      principled basis for deriving the Object method implementations in
      the face of arbitrary representation.  <br>
      <br>
          A class with a state description means that it has accessors
      for each <br>
          component, and has a canonical deconstruction pattern --
      that's it<br>
      <br>
    </font><font size="4" face="monospace">Saying that the state
      description is solely about access to components (both
      individually and in bulk) allows us to drop all of the structural
      restrictions we might be inclined to impose on such interfaces or
      classes -- they can be final or not, extend other classes or not,
      they can have whatever constructors they like, carriers can extend
      non-carriers and vice versa, etc.  <br>
      <br>
      We will call a class or interface that has a state description in
      its declaration a _deconstructible class_, and the elements of the
      state description _class components_.  Records become a restricted
      form of deconstructible classes.<br>
      <br>
    </font><font size="4" face="monospace">The rules about overriding
      components largely derive from the existing rules about overriding
      their corresponding accessor methods; subclasses can covariantly
      refine the type of an inherited superclass component, but cannot
      have a component of the same name but a (sufficiently) different
      type.  <br>
      <br>
      ## What's left?<br>
      <br>
      So, what's left?  Quite a lot, of course; we've addressed the "how
      do other classes and interfaces get pattern matching", but nothing
      else yet.  The "what's left" includes: <br>
      <br>
       - Reconstruction (withers)<br>
       - Deriving implementations of accessors<br>
       - Compact constructors for deconstructible classes<br>
       - Deriving / streamlining object method implementation<br>
      <br>
      We'll take these in turns, though I'm going to label some of these
      as "for future discussion" to indicate that they are lower on the
      priority list and guide discussions to the higher-priority
      items.  <br>
      <br>
      ### Reconstruction<br>
      <br>
      Reconstruction (withers) requires an underlying canonical
      constructor-deconstructor pair.  Records always have these, so
      they always qualify for reconstruction.  But we said earlier that
      we make no assumptions about the construction protocol of
      arbitrary deconstructible classes, so how do they qualify for
      reconstructibility?<br>
      <br>
      We have long struggled with the question of what aspects of this
      have to be explicitly declared vs what aspects can be reasonably
      inferred by structure.  Given that we've raised deconstructibility
      not only to a language feature, but to a prominent place in the
      class declaration, it seems reasonable to say that:<br>
      <br>
       - A constructor of a deconstructible class D is canonical if it
      matches the state description of D.<br>
       - A deconstructible class D is reconstructible by client C if D
      has a canonical constructor and that constructor is accessible to
      C.<br>
      <br>
      That is, given a deconstructible class, which has a canonical
      state description, we can structurally recognize when a
      constructor is canonical, and derive reconstruction if that
      constructor is present and accessible.  <br>
      <br>
      It may further be desirable to restrict reconstruction to final
      classes, as this reduces the risk of "decapitation", which seems
      to freak people out quite a lot when they learn about the risk (I
      think this is mostly "unfamiliarity bias", but is a restriction
      worth considering.)<br>
      <br>
      ### Derived fields in records<br>
      <br>
      By far the most common profile of "almost records" is "records
      that want to derive some state from their components and cache
      it."  The previous proposal addressed this through carrier
      classes; after some evaluation, I think it is better to handle
      this within records themselves.  <br>
      <br>
      We've recently exposed the "lazy constants" work through an API
      class, but the long-term goal has always been to sediment these
      into the language eventually.  Over there, there are discussions
      going on about "cached instance methods" or "lazy instance fields"
      would allow us to expose lazily derived, cached state in records
      without undermining the record imperative.  Of course, this
      mechanism would be available to classes other than records as
      well.  <br>
      <br>
      Extending the reach of records takes some pressure off of the use
      cases for carrier classes, as more things that are "almost record"
      can become real records.  So we'll let the work on laziness play
      out, and see to what extent it addresses the concerns about
      "records aren't expressive enough."  <br>
      <br>
      ### Nominal invocation<br>
      <br>
      Reconstruction leans on the nominality of components, but people
      have been wishing for nominal invocation of constructors and
      deconstructors as well for a long time.  To the extent we allow
      for nominal creation and deconstruction of records,
      deconstructible classes would be able to come along for that
      ride.  (But please, let's not discuss this now.)<br>
      <br>
      ### Derived accessors and compact constructors<br>
      <br>
      Deconstructible classes get the requirement for accessors for each
      component, but as currently stated, get no help in declaring them,
      because, unlike with records, the language is unaware of the
      mapping between the external API (as defined by the state
      description) and the internal representation.  <br>
      <br>
      In the previous iteration, we filled in that mapping with a
      `component` modifier on fields, which connected those dots, and
      therefore allowed derivation of the (often numerous) accessors
      whose external API _does_ align with the internal representation. 
      (This was a semantic claim: that the field called `x` and the
      component called `x` describe the same thing.)  We will come back
      later to explore whether this concept still carries its weight in
      the slimmed-down role for carrier classes.  <br>
      <br>
      Having severed the state description from the construction
      protocol, the implementation is free to choose its own
      construction protocol.  But many deconstructible classes are
      likely to choose a constructor that matches the state description,
      and in these cases, at the very least, we can elide the redundant
      signature declaration of the canonical constructor using the
      "compact constructor" syntax, as we do with records.  We may also
      further use the `component` fields to streamline the constructor,
      but given the slimmed-down role for carrier classes, this would
      also have to be reevaluated.  <br>
      <br>
      ### Object methods<br>
      <br>
      Having dropped the derivation of Object methods -- because we
      didn't really have a sufficiently principled basis for doing so --
      these implementations are likely to be either significant sources
      of boilerplate, or worse, forgotten about in deconstructible
      classes.  <br>
      <br>
      Our best story for this builds on the currently-dormant "concise
      method bodies" JEP, that allows us to delegate method
      implementations either to method references or to objects that
      implement the method, such as:<br>
      <br>
          boolean equals(Object other) __delegates_to
      <equalator-object><br>
      <br>
      paired with an API for constructing such objects (which could
      drive all of the Object methods, not just `equals`).  This is
      something that would benefit all classes, not just deconstructible
      ones.  (We will return to this topic when concise method bodies
      comes closer to the top of the priority queue.</font><font size="4" face="monospace">)<br>
      <br>
      ## Summary<br>
      <br>
      What we see here eventually gets to the same place -- suitable
      classes can participate in deconstruction, reconstruction, and any
      future nominal construction/deconstruction; the most common forms
      of "almost records" are absorbed into records; classes that are
      largely data holder classes can get more concise expression.  Some
      of these are deferred into the (possibly infinite) future, but
      almost all of these are more broadly applicable than what was
      outlined in the previous version.  And we reclaim the clarity that
      comes from records being the locus of derived members, rather than
      sprinkling invisible members into other classes.  </font><br>
    <br>
    <div class="moz-cite-prefix">On 1/13/2026 4:52 PM, Brian Goetz
      wrote:<br>
    </div>
    <blockquote cite="mid:a9b4d85d-29e9-4442-adb5-13e0f30637f3@oracle.com">
      
      <font size="4" face="monospace">Here's a snapshot of where my head
        is at with respect to extending the record goodies (including
        pattern matching) to a broader range of classes, deconstructors
        for classes and interfaces, and compatible evolution of
        records.  Hopefully this will unblock quite a few things.<br>
        <br>
        As usual, let's discuss concepts and directions rather than
        syntax.  <br>
        <br>
        <br>
        <br>
        # Data-oriented Programming for Java: Beyond records<br>
        <br>
        Everyone loves records; they allow us to create shallowly
        immutable data holder<br>
        classes -- which we can think of as "nominal tuples" -- derived
        from a concise<br>
        state description, and to destructure records through pattern
        matching.  But<br>
        records have strict constraints, and not all data holder classes
        fit into the<br>
        restrictions of records.  Maybe they have some mutable state, or
        derived or<br>
        cached state that is not part of the state description, or their
        representation<br>
        and their API do not match up exactly, or they need to break up
        their state<br>
        across a hierarchy.  In these classes, even though they may also
        be “data<br>
        holders”, the user experience is like falling off a cliff.  Even
        a small<br>
        deviation from the record ideal means one has to go back to a
        blank slate and<br>
        write explicit constructor declarations, accessor method
        declarations, and<br>
        Object method implementations -- and give up on destructuring
        through pattern<br>
        matching.  <br>
        <br>
        Since the start of the design process for records, we’ve kept in
        mind the goal<br>
        of enabling a broader range of classes to gain access to the
        "record goodies":<br>
        reduced declaration burden, participating in destructuring, and
        soon,<br>
        [reconstruction](<a class="moz-txt-link-freetext" href="https://openjdk.org/jeps/468" target="_blank">https://openjdk.org/jeps/468</a>).
        During the design of records, we<br>
        also explored a number of weaker semantic models that would
        allow for greater<br>
        flexibility. While at the time they all failed to live up to the
        goals _for<br>
        records_, there is a weaker set of semantic constraints we can
        impose that<br>
        allows for more flexibility and still enables the features we
        want, along with<br>
        some degree of syntactic concision that is commensurate with the
        distance from<br>
        the record-ideal, without fall-off-the-cliff behaviors.  <br>
        <br>
        Records, sealed classes, and destructuring with record patterns
        constitute the<br>
        first feature arc of "data-oriented programming" for Java. 
        After considering<br>
        numerous design ideas, we're now ready to move forward with the
        next "data<br>
        oriented programming" feature arc: _carrier classes_ (and
        interfaces.)<br>
        <br>
        ## Beyond record patterns<br>
        <br>
        Record patterns allow a record instance to be destructured into
        its components.<br>
        Record patterns can be used in `instanceof` and `switch`, and
        when a record<br>
        pattern is also exhaustive, will be usable in the upcoming
        [_pattern assignment<br>
        statement_](<a class="moz-txt-link-freetext" href="https://mail.openjdk.org/pipermail/amber-spec-experts/2026-January/004306.html" target="_blank">https://mail.openjdk.org/pipermail/amber-spec-experts/2026-January/004306.html</a>)
        feature.  <br>
        <br>
        In exploring the question "how will classes be able to
        participate in the same<br>
        sort of destructuring as records", we had initially focused on a
        new form of<br>
        declaration in a class -- a "deconstructor" -- that operated as
        a constructor in<br>
        reverse. Just as a constructor takes component values and
        produces an aggregate<br>
        instance, a deconstructor would take an aggregate instance and
        recover its<br>
        component values.  <br>
        <br>
        But as this exploration played out, the more interesting
        question turned out to<br>
        be: which classes are suitable for destructuring in the first
        place? And the<br>
        answer to that question led us to a different approach for
        expressing<br>
        deconstruction.  The classes that are suitable for destructuring
        are those that,<br>
        like records, are little more than carriers for a specific tuple
        of data. This<br>
        is not just a thing that a class _has_, like a constructor or
        method, but<br>
        something a class _is_.  And as such, it makes more sense to
        describe<br>
        deconstruction as a top-level property of a class.  This, in
        turn, leads to a<br>
        number of simplifications.  <br>
        <br>
        ## The power of the state description<br>
        <br>
        Records are a semantic feature; they are only incidentally
        concise.  But they<br>
        _are_ concise; when we declare a record<br>
        <br>
            record Point(int x, int y) { ... }<br>
        <br>
        we automatically get a sensible API (canonical constructor,
        deconstruction<br>
        pattern, accessor methods for each component) and implementation
        (fields,<br>
        constructor, accessor methods, Object methods.)  We can
        explicitly specify most<br>
        of these (except the fields) if we like, but most of the time we
        don't have to,<br>
        because the default is exactly what we want.<br>
        <br>
        A record is a shallowly-immutable, final class whose API and
        representation are<br>
        _completely defined_ by its _state description_.  (The slogan
        for records is<br>
        "the state, the whole state, and nothing but the state.")  The
        state description<br>
        is the ordered list of _record components_ declared in the
        record's header.  A<br>
        component is more than a mere field or accessor method; it is an
        API element on<br>
        its own, describing a state element that instances of the class
        have.  <br>
        <br>
        The state description of a record has several desirable
        properties: <br>
        <br>
         - The components in the order specified, are the _canonical_
        description of the<br>
           record's state.<br>
         - The components are the _complete_ description of the record’s
        state.  <br>
         - The components are _nominal_; their names are a committed
        part of the<br>
           record's API.  <br>
        <br>
        Records derive their benefits from making two commitments:<br>
        <br>
         - The _external_ commitment that the data-access API of a
        record (constructor,<br>
           deconstruction pattern, and component accessor methods) is
        defined by the<br>
           state description.  <br>
         - The _internal_ commitments that the _representation_ of the
        record (its<br>
           fields) is also completely defined by the state description.<br>
        <br>
        These semantic properties are what enable us to derive almost
        everything about<br>
        records.  We can derive the API of the canonical constructor
        because the state<br>
        description is canonical.  We can derive the API for the
        component accessor<br>
        methods because the state description is nominal.  And we can
        derive a<br>
        deconstruction pattern from the accessor methods because the
        state description<br>
        is complete (along with sensible implementations for the
        state-related `Object`<br>
        methods.)<br>
        <br>
        The internal commitment that the state description is also the
        representation<br>
        allows us to completely derive the rest of the implementation. 
        Records get a<br>
        (private, final) field for each component, but more importantly,
        there is a<br>
        clear mapping between these fields and their corresponding
        components, which is<br>
        what allows us to derive the canonical constructor and accessor
        method<br>
        implementations.  <br>
        <br>
        Records can additionally declare a _compact constructor_ that
        allows us to elide<br>
        the boilerplate aspects of record constructors -- the argument
        list and field<br>
        assignments -- and just specify the code that is _not_
        mechanically derivable.<br>
        This is more concise, less error-prone, and easier to read:<br>
        <br>
            record Rational(int num, int denom) { <br>
                Rational { <br>
                    if (denom == 0)<br>
                        throw new IllegalArgumentException("denominator
        cannot be zero");<br>
                }<br>
            }<br>
        <br>
        is shorthand for the more explicit<br>
        <br>
            record Rational(int num, int denom) { <br>
                Rational(int num, int denom) { <br>
                    if (denom == 0)<br>
                        throw new IllegalArgumentException("denominator
        cannot be zero");<br>
                    this.num = num;<br>
                    this.denom = denom;<br>
                }<br>
            }<br>
        <br>
        While compact constructors are pleasantly concise, the more
        important benefit is<br>
        that by eliminating the mechanically derivable code, the "more
        interesting" code<br>
        comes to the fore.  <br>
        <br>
        Looking ahead, the state description is a gift that keeps on
        giving.  These<br>
        semantic commitments are enablers for a number of potential
        future language and<br>
        library features for managing object lifecycle, such as: <br>
        <br>
         - [Reconstruction](<a class="moz-txt-link-freetext" href="https://openjdk.org/jeps/468" target="_blank">https://openjdk.org/jeps/468</a>)
        of record instances, allowing<br>
           the appearance of controlled mutation of record state.<br>
         - Automatic marshalling and unmarshalling of record instances.<br>
         - Instantiating or destructuring record instances identifying
        components<br>
           nominally rather than positionally.<br>
        <br>
        ### Reconstruction<br>
        <br>
        JEP 468 proposes a mechanism by which a new record instance can
        be derived from<br>
        an existing one using syntax that is evocative of direct
        mutation, via a `with`<br>
        expression: <br>
        <br>
            record Complex(double re, double im) { }<br>
            Complex c = ...<br>
            Complex cConjugate = c with { im = -im; }; <br>
        <br>
        The block on the right side of `with` can contain any Java
        statements, not just<br>
        assignments.  It is enhanced with mutable variables (_component
        variables_) for<br>
        each component of the record, initialized to the value of that
        component in the<br>
        record instance on the left, the block is executed, and a new
        record instance is<br>
        created whose component values are the ending values of the
        component variables.  <br>
        <br>
        A reconstruction expression implicitly destructures the record
        instance using<br>
        the canonical deconstruction pattern, executes the block in a
        scope enhanced<br>
        with the component variables, and then creates a new record
        using the canonical<br>
        constructor.  Invariant checking is centralized in the canonical
        constructor, so<br>
        if the new state is not valid, the reconstruction will fail. 
        JEP 468 has been<br>
        "on hold" for a while, primarily because we were waiting for
        sufficient<br>
        confidence that there was a path to extending it to suitable
        classes before<br>
        committing to it for records.  The ideal path would be for those
        classes to also<br>
        support a notion of canonical constructor and deconstruction
        pattern.  <br>
        <br>
        Careful readers will note a similarity between the
        transformation block of a<br>
        `with` expression and the body of a compact constructor.  In
        both cases, the<br>
        block is "preloaded" with a set of component variables,
        initialized to suitable<br>
        starting values, the block can mutate those variables as
        desired, and upon<br>
        normal completion of the block, those variables are passed to a
        canonical<br>
        constructor to produce the final result.  The main difference is
        where the<br>
        starting values come from; for a compact constructor, it is from
        the constructor<br>
        parameters, and for a reconstruction expression, it is from the
        canonical<br>
        deconstruction pattern of the source record to the left of
        `with`.<br>
         <br>
        ### Breaking down the cliff<br>
        <br>
        Records make a strong semantic commitment to derive both their
        API and<br>
        representation from the state description, and in return get a
        lot of help from<br>
        the language.  We can now turn our attention to smoothing out
        "the cliff" --<br>
        identifying weaker semantic commitments that classes can make
        that would still<br>
        allow classes to get _some_ help from the language.  And
        ideally, the amount of<br>
        help you give up would be proportional to the degree of
        deviation from the<br>
        record ideal.<br>
        <br>
        With records, we got a lot of mileage out of having a complete,
        canonical,<br>
        nominal state description.  Where the record contract is
        sometimes too<br>
        constraining is the _implementation_ contract that the
        representation aligns<br>
        exactly with the state description, that the class is final,
        that the fields are<br>
        final, and that the class may not extend anything but
        `Record`.  <br>
        <br>
        Our path here takes one step back and one step forward: keeping
        the external<br>
        commitment to the state description, but dropping the internal
        commitment that<br>
        the state description _is_ the representation -- and then
        _adding back_ a simple<br>
        mechanism for mapping fields representing components back to
        their corresponding<br>
        components, where practical.  (With records, because we derive
        the<br>
        representation from the state description, this mapping can be
        safely inferred.)  <br>
        <br>
        As a thought experiment, imagine a class that makes the external
        commitment to a<br>
        state description -- that the state description is a complete,
        canonical,<br>
        nominal description of its state -- but is on its own to provide
        its<br>
        representation.  What can we do for such a class?  Quite a bit,
        actually.  For<br>
        all the same reasons we can for records, we can derive the API
        requirement for a<br>
        canonical constructor and component accessor methods.  From
        there, we can derive<br>
        both the requirement for a canonical deconstruction pattern, and
        also the<br>
        implementation of the deconstruction pattern (as it is
        implemented in terms of<br>
        the accessor methods). And since the state description is
        complete, we can<br>
        further derive sensible default implementations of the Object
        methods `equals`,<br>
        `hashCode`, and `toString` in terms of the accessor methods as
        well. And given<br>
        that there is a canonical constructor and deconstruction
        pattern, it can also<br>
        participate in reconstruction.  The author would just have to
        provide the<br>
        fields, accessor methods, and canonical constructor.  This is
        good progress, but<br>
        we'd like to do better.<br>
        <br>
        What enables us to derive the rest of the implementation for
        records (fields,<br>
        constructor, accessor methods, and Object methods) is the
        knowledge of how the<br>
        representation maps to the state description.  Records commit to
        their state<br>
        description _being_ the representation, so is is a short leap
        from there to a<br>
        complete implementation.  <br>
        <br>
        To make this more concrete, let's look at a typical "almost
        record" class, a<br>
        carrier for the state description `(int x, int y,
        Optional<String> s)` but which<br>
        has made the representation choice to internally store `s` as a
        nullable<br>
        `String`.  <br>
        <br>
        ```<br>
        class AlmostRecord { <br>
            private final int x;<br>
            private final int y;<br>
            private final String s;                                 // *<br>
        <br>
            public AlmostRecord(int x, int y, Optional<String> s)
        { <br>
                this.x = x;<br>
                this.y = y;<br>
                this.s = s.orElse(null);                            // *<br>
            }<br>
        <br>
            public int x() { return x; }<br>
            public int y() { return y; }<br>
            public Optional<String> s() { <br>
                return Optional.ofNullable(s);                      // *<br>
            }<br>
        <br>
            public boolean equals(Object other) { ... }     // derived
        from x(), y(), s()<br>
            public int hashCode() { ... }                   //    "<br>
            public String toString() { ... }                //    "<br>
        }<br>
        ```<br>
        <br>
        The main differences between this class and the expansion of its
        record analogue<br>
        are the lines marked with a `*`; these are the ones that deal
        with the disparity<br>
        between the state description and the actual representation.  It
        would be nice<br>
        if the author of this class _only_ had to write the code that
        was different from<br>
        what we could derive for a record; not only would this be
        pleasantly concise,<br>
        but it would mean that all the code that _is_ there exists to
        capture the<br>
        differences between its representation and its API.  <br>
        <br>
        ## Carrier classes<br>
        <br>
        A _carrier class_ is a normal class declared with a state
        description.  As with<br>
        a record, the state description is a complete, canonical,
        nominal description of<br>
        the class's state.  In return, the language derives the same API
        constraints as<br>
        it does for records: canonical constructor, canonical
        deconstruction pattern,<br>
        and component accessor methods.<br>
        <br>
           class Point(int x, int y) {                // class, not
        record!<br>
               // explicitly declared representation<br>
        <br>
               ...<br>
        <br>
               // must have a constructor taking (int x, int y)<br>
               // must have accessors for x and y<br>
               // supports a deconstruction pattern yielding (int x, int
        y)<br>
           }<br>
        <br>
        Unlike a record, the language makes no assumptions about the
        object's<br>
        representation; the class author has to declare that just as
        with any other<br>
        class.  <br>
        <br>
        Saying the state description is "complete" means that it carries
        all the<br>
        “important” state of the class -- if we were to extract this
        state and recreate<br>
        the object, that should yield an “equivalent” instance.  As with
        records, this<br>
        can be captured by tying together the behavior of construction,
        accessors, and<br>
        equality:<br>
        <br>
        ```<br>
        Point p = ...<br>
        Point q = new Point(p.x(), p.y());<br>
        assert p.equals(q);<br>
        ```<br>
        <br>
        We can also derive _some_ implementation from the information we
        have so far; we<br>
        can derive sensible implementations of the `Object` methods
        (implemented in terms<br>
        of component accessor methods) and we can derive the canonical
        deconstruction<br>
        pattern (again in terms of the component accessor methods).  And
        from there, we<br>
        can derive support for reconstruction (`with` expressions.) 
        Unfortunately, we<br>
        cannot (yet) derive the bulk of the state-related
        implementation: the canonical<br>
        constructor and component accessor methods.  <br>
        <br>
        ### Component fields and accessor methods<br>
        <br>
        One of the most tedious aspects of data-holder classes is the
        accessor methods;<br>
        there are often many of them, and they are almost always pure
        boilerplate.  Even<br>
        though IDEs can reduce the writing burden by generating these
        for us, readers<br>
        still have to slog through a lot of low-information code -- just
        to learn that<br>
        they didn't actually need to slog through that code after all. 
        We can derive<br>
        the implementation of accessor methods for records because
        records make the<br>
        internal commitment that the components are all backed with
        individual fields<br>
        whose name and type align with the state description.  <br>
        <br>
        For a carrier class, we don't know whether _any_ of the
        components are directly<br>
        backed by a single field that aligns to the name or type of the
        component.  But<br>
        it is a pretty good bet that many carrier class components will
        do exactly this<br>
        for at least _some_ of their fields.  If we can tell the
        language that this<br>
        correspondence is not merely accidental, the language can do
        more for us.<br>
        <br>
        We do so by allowing suitable fields of a carrier class to be
        declared as<br>
        `component` fields.  (As usual at this stage, syntax is
        provisional, but not <br>
        currently a topic for discussion.)  A component field must have
        the same name<br>
        and type as a component of the current class (though it need not
        be `private` or<br>
        `final`, as record fields are.)  This signals that this field
        _is_ the<br>
        representation for the corresponding component, and hence we can
        derive the<br>
        accessor method for this component as well.  <br>
        <br>
        ```<br>
        class Point(int x, int y) { <br>
            private /* mutable */ component int x;<br>
            private /* mutable */ component int y;<br>
        <br>
            // must have a canonical constructor, but (so far) must be
        explicit<br>
            public Point(int x, int y) { <br>
                this.x = x;<br>
                this.y = y;<br>
            }<br>
        <br>
            // derived implementations of accessors for x and y<br>
            // derived implementations of equals, hashCode, toString<br>
        }<br>
        ```<br>
        <br>
        This is getting better; the class author had to bring the
        representation and the<br>
        mapping from representation to components (in the form of the
        `component`<br>
        modifier), and the canonical constructor.  <br>
        <br>
        ### Compact constructors<br>
        <br>
        Just as we are able to derive the accessor method implementation
        if we are<br>
        given an explicit correspondence between a field and a
        component, we can do the<br>
        same for constructors.  For this, we build on the notion of
        _compact<br>
        constructors_ that was introduced for records.  <br>
        <br>
        As with a record, a compact constructor in a carrier class is a
        shorthand for a<br>
        canonical constructor, which has the same shape as the state
        description, but<br>
        which is freed of the responsibility of actually committing the
        ending value of<br>
        the component parameters to the fields.  The main difference is
        that for a<br>
        record, _all_ of the components are backed by a component field,
        whereas for a<br>
        carrier class, only some of them might be.  But we can
        generalize compact<br>
        constructors by freeing the author of the responsibility to
        initialize the<br>
        _component_ fields, while leaving them responsible for
        initializing the rest of<br>
        the fields.  In the limiting case where all components are
        backed by component<br>
        fields, and there is no other logic desired in the constructor,
        the compact<br>
        constructor may be elided.  <br>
        <br>
        For our mutable `Point` class, this means we can elide nearly
        everything, except<br>
        the field declarations themselves: <br>
        <br>
        ```<br>
        class Point(int x, int y) { <br>
            private /* mutable */ component int x;<br>
            private /* mutable */ component int y;<br>
        <br>
            // derived compact constructor<br>
            // derived accessors for x, y<br>
            // derived implementations of equals, hashCode, toString<br>
        }<br>
        ```<br>
        <br>
        We can think of this class as having an implicit empty compact
        constructor,<br>
        which in turn means that the component fields `x` and `y` are
        initialized from<br>
        their corresponding constructor parameters.  There are also
        implicitly derived<br>
        accessor methods for each component, and implementations of
        `Object` methods<br>
        based on the state description.  <br>
        <br>
        This is great for a class where all the components are backed by
        fields, but<br>
        what about our `AlmostRecord` class?  The story here is good as
        well; we can<br>
        derive the accessor methods for the components backed by
        component fields, and<br>
        we can elide the initialization of the component fields from the
        compact<br>
        constructor, meaning that we _only_ have to specify the code for
        the parts that<br>
        deviate from the "record ideal": <br>
        <br>
        ```<br>
        class AlmostRecord(int x, <br>
                           int y, <br>
                           Optional<String> s) { <br>
        <br>
            private final component int x;<br>
            private final component int y;<br>
            private final String s;<br>
        <br>
            public AlmostRecord { <br>
                this.s = s.orElse(null); <br>
                // x and y fields implicitly initialized<br>
            }<br>
        <br>
            public Optional<String> s() { <br>
                return Optional.ofNullable(s);  <br>
            }<br>
        <br>
            // derived implementation of x and y accessors<br>
            // derived implementation of equals, hashCode, toString<br>
        }<br>
        ```<br>
        <br>
        Because so many real-world almost-records differ from their
        record ideal in<br>
        minor ways, we expect to get a significant concision benefit for
        most carrier<br>
        classes, as we did for `AlmostRecord`.  As with records, if we
        want to<br>
        explicitly implement the constructor, accessor methods, or
        `Object` methods, we<br>
        are still free to do so. <br>
        <br>
        ### Derived state<br>
        <br>
        One of the most frequent complaints about records is the
        inability to derive<br>
        state from the components and cache it for fast retrieval.  With
        carrier<br>
        classes, this is simple: declare a non-component field for the
        derived quantity,<br>
        initialize it in the constructor, and provide an accessor: <br>
        <br>
        ```<br>
        class Point(int x, int y) { <br>
            private final component int x;<br>
            private final component int y;<br>
            private final double norm;<br>
        <br>
            Point { <br>
                norm = Math.hypot(x, y);<br>
            }<br>
        <br>
            public double norm() { return norm; }<br>
        <br>
            // derived implementation of x and y accessors<br>
            // derived implementation of equals, hashCode, toString<br>
        }<br>
        ```<br>
        <br>
        ### Deconstruction and reconstruction<br>
        <br>
        Like records, carrier classes automatically acquire
        deconstruction patterns that<br>
        match the canonical constructor, so we can destructure our
        `Point` class as if<br>
        it were a record: <br>
        <br>
            case Point(var x, var y): <br>
        <br>
        Because reconstruction (`with`) derives from a canonical
        constructor and<br>
        corresponding deconstruction pattern, when we support
        reconstruction of records,<br>
        we will also be able to do so for carrier classes:<br>
        <br>
            point = point with { x = 3; }<br>
        <br>
        ## Carrier interfaces<br>
        <br>
        A state description makes sense on interfaces as well.  It makes
        the statement<br>
        that the state description is a complete, canonical, nominal
        description of the<br>
        interface's state (subclasses are allowed to add additional
        state), and<br>
        accordingly, implementations must provide accessor methods for
        the components.<br>
        This enables such interfaces to participate in pattern matching:<br>
        <br>
        ```<br>
        interface Pair<T,U>(T first, U second) {<br>
            // implicit abstract accessors for first() and second()<br>
        }<br>
        <br>
        ...<br>
        <br>
        if (o instanceof Pair(var a, var b)) { ... }<br>
        ```<br>
        <br>
        Along with the upcoming feature for pattern assignment in
        foreach-loop headers,<br>
        if `Map.Entry` became a carrier interface (which it will), we
        would be able to<br>
        iterate a `Map` like:<br>
        <br>
            for (Map.Entry(var key, var val) : map.entrySet()) { ... }<br>
        <br>
        It is a common pattern in libraries to export an interface that
        is sealed to a<br>
        single private implementation.  In this pattern, the interface
        and<br>
        implementation can share a common state description: <br>
        <br>
        ```<br>
        public sealed interface Pair<T,U>(T first, U second) { }<br>
        <br>
        private record PairImpl<T, U>(T first, U second)
        implements Pair<T, U> { }<br>
        ```<br>
        <br>
        Compared to the old way of doing this, we get enhanced
        semantics, better type<br>
        checking, and more concision.  <br>
        <br>
        ### Extension<br>
        <br>
        The main obligation of a carrier class author is to ensure that
        the fundamental<br>
        claim -- that the state description is a complete, canonical,
        nominal<br>
        description of the object's state -- is actually true.  This
        does not rule out<br>
        having the representation of a carrier class spread out over a
        hierarchy, so<br>
        unlike records, carrier classes are not required to be final or
        concrete, nor<br>
        are they restricted in their extension.<br>
        <br>
        There are several cases that arise when carrier classes can
        participate in<br>
        extension:<br>
        <br>
         - A carrier class extends a non-carrier class;<br>
         - A non-carrier class extends a carrier class;<br>
         - A carrier class extends another carrier class, where all of
        the superclass<br>
           components are subsumed by the subclass state description; <br>
         - A carrier class extends another carrier class, but there are
        one or more<br>
           superclass components that are not subsumed by the subclass
        state<br>
           description.<br>
        <br>
        Extending a non-carrier class with a carrier class will usually
        be motiviated by<br>
        the desire to "wrap" a state description around an existing
        hierarchy which we<br>
        cannot or do not want to modify directly, but we wish to gain
        the benefits of<br>
        deconstruction and reconstruction.  Such an implementation would
        have to ensure<br>
        that the class actually conforms to the state description, and
        that the<br>
        canonical constructor and component accessors are implemented.  <br>
        <br>
        When one carrier class extends another, the more straightforward
        case is that it<br>
        simply adds new components to the state description of the
        superclass.  For<br>
        example, given our `Point` class:<br>
        <br>
        ```<br>
        class Point(int x, int y) { <br>
            component int x; <br>
            component int y;<br>
        <br>
            // everything else for free!<br>
        }<br>
        ```<br>
        <br>
        we can use this as the base class for a 3d point class: <br>
        <br>
        ```<br>
        class Point3d(int x, int y, int z) extends Point { <br>
            component int z;<br>
        <br>
            Point3d {<br>
                super(x, y);<br>
            }<br>
        }<br>
        ```<br>
        <br>
        In this case -- because the superclass components are all part
        of the subclass<br>
        state description -- we can actually omit the constructor as
        well, because we<br>
        can derive the association between subclass components and
        superclass<br>
        components, and thereby derive the needed super-constructor
        invocation.  So we<br>
        could actually write:<br>
        <br>
        ```<br>
        class Point3d(int x, int y, int z) extends Point { <br>
            component int z;<br>
        <br>
            // everything else for free!<br>
        }<br>
        ```<br>
        <br>
        One might think that we would need some marking on the `x` and
        `y` components of<br>
        `Point3d` to indicate that they map to the corresponding
        components of `Point`,<br>
        as we did for associating component fields with their
        corresponding components.<br>
        But in this case, we need no such marking, because there is no
        way that an `int<br>
        x` component of `Point` and an `int x` component of its subclass
        could possibly<br>
        refer to different things -- since they both are tied to the
        same `int x()`<br>
        accessor methods.  So we can safely infer which subclass
        components are managed<br>
        by superclasses, just by matching up their names and types.<br>
        <br>
        In the other carrier-to-carrier extension case, where one or
        more superclass<br>
        components are _not_ subsumed by the subclass state description,
        it is necessary<br>
        to provide an explicit `super` constructor call in the subclass
        constructor.  <br>
        <br>
        A carrier class may be also declared abstract; the main effect
        of this is that<br>
        we will not derive `Object` method implementations, instead
        leaving that for the<br>
        subclass to do.<br>
        <br>
        ### Abstract records<br>
        <br>
        This framework also gives us an opportunity to relax one of the
        restrictions on<br>
        records: that records can't extend anything other than
        `java.lang.Record`.  We<br>
        can also allow records to be declared `abstract`, and for
        records to extend<br>
        abstract records.  <br>
        <br>
        Just as with carrier classes that extend other carrier classes,
        there are two<br>
        cases: when the component list of the superclass is entirely
        contained within<br>
        that of the subclass, and when one or more superclass components
        are derived<br>
        from subclass components (or are constant), but are not
        components of the<br>
        subclass itself.  And just as with carrier classes, the main
        difference is<br>
        whether an explicit `super` call is required in the subclass
        constructor.  <br>
        <br>
        When a record extends an abstract record, any components of the
        subclass that<br>
        are also components of the superclass do not implicitly get
        component fields in<br>
        the subclass (because they are already in the superclass), and
        they inherit the<br>
        accessor methods from the superclass.  <br>
        <br>
        ### Records are carriers too<br>
        <br>
        With this framework in place, records can now be seen to be
        "just" carrier<br>
        classes that are implicitly final, extend `java.lang.Record`,
        that implicitly<br>
        have private final component fields for each component, and can
        have no other<br>
        fields.  <br>
        <br>
        ## Migration compatibility <br>
        <br>
        There will surely be some existing classes that would like to
        become carrier<br>
        classes.  This is a compatible migration as long as none of the
        mandated members<br>
        conflict with existing members of the class, and the class
        adheres to the<br>
        requirement that the state description is a complete, canonical,
        and nominal<br>
        description of the object state.  <br>
        <br>
        ### Compatible evolution of records and carrier classes<br>
        <br>
        To date, libraries have been reluctant to use records in public
        APIs because<br>
        of the difficulty of evolving them compatibly.  For a record: <br>
        <br>
        ```<br>
        record R(A a, B b) { }<br>
        ```<br>
        <br>
        that wants to evolve by adding new components:<br>
        <br>
        ```<br>
        record R(A a, B b, C c, D d) { }<br>
        ```<br>
        <br>
        we have several compatibility challenges to manage.  As long as
        we are only<br>
        adding and not removing/renaming, accessor method invocations
        will continue to<br>
        work. And existing constructor invocations can be allowed to
        continue work by<br>
        explicitly adding back a constructor that has the old shape: <br>
        <br>
        ```<br>
        record R(A a, B b, C c, D d) { <br>
        <br>
            // Explicit constructor for old shape required<br>
            public R(A a, B b) { <br>
                this(a, b, DEFAULT_C, DEFAULT_D);<br>
            }<br>
        <br>
        }<br>
        ```<br>
        <br>
        But, what can we do about existing uses of record _patterns_? 
        While the<br>
        translation of record patterns would make adding components
        binary-compatible,<br>
        it would not be source-compatible, and there is no way to
        explicitly add a<br>
        deconstruction pattern for the old shape as we did with the
        constructor.  <br>
        <br>
        We can take advantage of the simplification offered by there
        being _only_ the<br>
        canonical deconstruction pattern, and allow uses of
        deconstruction patterns to<br>
        supply nested patterns for any _prefix_ of the component list. 
        So for the<br>
        evolved record R: <br>
        <br>
            case R(P1, P2)<br>
        <br>
        would be interpreted as:<br>
        <br>
            case R(P1, P2, _, _)<br>
        <br>
        where `_` is the match-all pattern.  This means that one can
        compatibly evolve a<br>
        record by only adding new components at the end, and adding a
        suitable<br>
        constructor for compatibility with existing constructor
        invocations.<br>
        <br>
      </font> </blockquote>
    <br><br></blockquote></div></div></body></html>