<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">
        <blockquote type="cite">
          <div>I think you have done a good job describing the pro of
            that model but weirdly not list the cons of that model.<br data-mce-bogus="1">
          </div>
        </blockquote>
        <br>
        I think we described the con pretty clearly: .val is ugly, and
        this puts it in people's face.  This point was mentioned
        multiple times during the discussions.  But the notable thing
        is: no one has raised other cons.  The con is syntax.  <br>
        <br>
        All your points here are basically a dressed-up version of this
        same issue: at least in some cases, some users will be grumpy
        that the good name goes to the thing they don't want.  And this
        is a point we are painfully aware of, so none of this is
        particularly new.  <br>
        <br>
        And we have explored all the positions on this (Point is ref,
        Point is val, let the user pick two names, let the declarer
        choose, etc), and they all have downsides.  Specifically, we
        explored having `ref-default` and `val-default` as
        declaration-site options; this "gives the user more control"
        (developers love knobs!)  But it also imposes a significant
        cognitive load on all developers: people no longer know what
        `Point` means.  Is it nullable?  Is it a reference?  You have to
        look it up, or "carry around a mental database."  If anyone has
        the choices, then everyone has more responsibility.  And given
        that the performance differences between Point.ref and Point.val
        accrue pretty much exclusively in the heap, which is to say,
        apply only to implementation code and not API, sticking the
        implementation with this burden seems resaonable.  <br>
        <br>
        Honestly, I think this is entirely a syntax concern; .val is
        ugly.  Open to better ideas here, though many attempts have
        already been made.  (If we're at the "all we have left to
        complain about is syntax" point, then we're winning!)  <br>
        <br>
        <br>
      </font></font><br>
    <div class="moz-cite-prefix">On 6/29/2022 10:38 AM, Remi Forax
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:2091250374.631588.1656513488696.JavaMail.zimbra@u-pem.fr">
      
      <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" <a class="moz-txt-link-rfc2396E" href="mailto:brian.goetz@oracle.com"><brian.goetz@oracle.com></a><br>
            <b>To: </b>"Kevin Bourrillion" <a class="moz-txt-link-rfc2396E" href="mailto:kevinb@google.com"><kevinb@google.com></a><br>
            <b>Cc: </b>"daniel smith" <a class="moz-txt-link-rfc2396E" href="mailto:daniel.smith@oracle.com"><daniel.smith@oracle.com></a>,
            "valhalla-spec-experts"
            <a class="moz-txt-link-rfc2396E" href="mailto:valhalla-spec-experts@openjdk.java.net"><valhalla-spec-experts@openjdk.java.net></a><br>
            <b>Sent: </b>Thursday, June 23, 2022 9:01:24 PM<br>
            <b>Subject: </b>Re: User model stacking: current status<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;"><br>
            <div class="moz-cite-prefix">On 6/15/2022 12:41 PM, Kevin
              Bourrillion wrote:<br>
            </div>
            <blockquote cite="mid:CAGKkBkttZ35rvuZ7Exfe6Ozh1CJS0NSmTFKMrQ-K+sW1N_66Vg@mail.gmail.com">All
              else being equal, the idea to use "inaccessible value
              type" over "value type doesn't exist" feels very good and
              simplifying, with the main problem that the syntax can't
              help but be gross.</blockquote>
            <br>
            <font size="4"><font face="monospace">A few weeks in, and
                this latest stacking is still feeling pretty good:<br>
                <br>
                 - There are no coarse buckets any more; there are just
                identity classes and value classes.  <br>
                 - Value classes have ref and val companion types with
                the obvious properties.  (Notably, refs are always
                atomic.)<br>
                 - For `value class C`, C as a type is an alias for
                `C.ref`.  <br>
                 - The bucket formerly known as B2 becomes "value class,
                whose .val type is private."  This is the default for a
                value class.  <br>
                 - The bucket formerly known as B3a is denoted by
                explicitly making the val companion public, with a
                public modifier on a "member" of the class.  <br>
                 - The bucket formerly known as B3n is denoted by
                explicitly making the </font></font><font size="4"><font face="monospace"><font size="4"><font face="monospace">val
                    companion </font></font>public and non-atomic,
                again using modifiers.  <br>
                <br>
                I went and updated the State of the Values document to
                use the new terminology, test-driving some new syntax. 
                (Usual rules: syntax comments are premature at this
                time.)  I was very pleased with the result, because
                almost all the changes were small changes in terminology
                (e.g., "value companion type"), and eliminating the
                clumsy distinction between value classes and primitive
                classes.  Overall the structure remains the same, but
                feels more compact and clean.  MD source is below, for
                review.  <br>
                <br>
                Kevin's two questions remain, but I don't think they get
                in the way of refining the model in this way:<br>
                <br>
                 - Have we made the right choices around == ?<br>
                 - Are we missing a big opportunity by not spelling
                Complex.val with a bang?  </font></font></blockquote>
          <div><br>
          </div>
          <div>I think you have done a good job describing the pro of
            that model but weirdly not list the cons of that model.<br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div>I see three reasons your proposed model, let's call it
            the companion class model, needs improvements.<br data-mce-bogus="1">
          </div>
          <div>It fails our moto, the companion class model and the VM
            models are not aligned and the performance model is a "sigil
            for performance" model.<br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div>It fails our moto (code like a class, works like an int):</div>
          <div>If i say that an Image is an array of pixels with each
            pixel have three colors,</div>
          <div>the obvious translation is not the right one:<br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div>   class Image {<br data-mce-bogus="1">
          </div>
          <div>     Pixel[][] pixels;<br data-mce-bogus="1">
          </div>
          <div>   }<br data-mce-bogus="1">
          </div>
          <div>   value record Pixel(Color red, Color green, Color blue)
            {}<br data-mce-bogus="1">
          </div>
          <div>   value record Color(byte value) {}</div>
          <div><br data-mce-bogus="1">
          </div>
          <div>because a value class is nullable, only it's companion
            class is not nullable, the correct code is</div>
          <div>
            <div>  class Image {</div>
            <div>     Pixel.val[][] pixels;</div>
            <div>   }</div>
            <div>   value record Pixel(Color.val red, Color.val green,
              Color.val blue) {}</div>
            <div>   value record Color(byte value) {}</div>
            <br data-mce-bogus="1">
          </div>
          <div>Color and byte does not work the same way, it's not code
            like a class works like an int but code like a class, works
            like an Integer.</div>
          <div><br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div>The VM models and the Java model are not aligned:<br data-mce-bogus="1">
          </div>
          <div>For the VM model, L-type and Q-type on equal footing, not
            one is more important than the other, but the companion
            class model you propose makes the value class a first
            citizen and the companion class a second citizen.<br data-mce-bogus="1">
          </div>
          <div>We know that when the Java model and the VM model are not
            aligned, bugs will lie in between. Those can be mild bugs,
            by example you can throw a checked exception from a method
            not declaring that exception or painful bugs in the case of
            generics or serialization.</div>
          <div>I think we should list all the cases where the Java Model
            and the VM model disagree to see the kind of bugs we will
            ask the future generation to solve.<br data-mce-bogus="1">
          </div>
          <div>By example, having a value class with a default
            constructor and public companion class looks like a lot like
            a deserialization bug to me, in both case you are able to
            produce an instance that bypass the constructor.</div>
          <div>The other problem is for the other languages than Java.
            Do those languages will have to define a companion class or
            a companion class is purely a javac artifact the same way an
            attribute like InnerClass is.<br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div>The proposed performance model is a "sigil for
            performance" model.<br data-mce-bogus="1">
          </div>
          <div>There is a tradeoff between the safety of the reference
            vs the performance of flattened value type. In the proposed
            model, the choice is not done by the maintainer of the class
            but by the user of the class. This is not fully true, the
            maintainer of the class can make the companion class private
            choosing safety but it can not choose performance. The
            performance has to be chosen by the user of the class.<br>
          </div>
          <div>This is unlike everything we know in Java, this kind of
            model where the user choose performance is usually called
            "sigil for performance", the user has to add some magical
            keywords or sigil to get performance.<br data-mce-bogus="1">
          </div>
          <div>A good example of such performance model is the keyword
            "register" in C. You have to opt-in at use site to get
            performance.<br>
          </div>
          <div>Moreover unlike in C, in Java we also have to take care
            of the fact that adding .val is not a backward compatible
            change, if a value class is used in a public method a user
            can not change it to its companion class after the fact.</div>
          <div>We know from the errors of past that a "sigil for
            performance" model is a terrible model.<br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div>Overall, i don't think it's the wrong model, but it
            over-rotates on the notion of reference value class, it's
            refreshing because in the past we had the tendency to
            over-rotate on the notion of flattened value class.<br data-mce-bogus="1">
          </div>
          <div>I really think that this model can be improved by
            allowing top-level value class to be declared either as
            reference or as value and the companion class to be either a
            value class projection or a reference class projection so
            the Java model and the VM model will be more in sync.<br data-mce-bogus="1">
          </div>
          <div><br data-mce-bogus="1">
          </div>
          <div>RĂ©mi<br data-mce-bogus="1">
          </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"><font face="monospace"><br>
                <br>
                <br>
                # State of Valhalla<br>
                ## Part 2: The Language Model {.subtitle}<br>
                <br>
                #### Brian Goetz {.author}<br>
                #### June 2022 {.date}<br>
                <br>
                > _This is the second of three documents describing
                the current State of<br>
                  Valhalla.  The first is [The Road to
                Valhalla](01-background); the<br>
                  third is [The JVM Model](03-vm-model)._<br>
                <br>
                This document describes the directions for the Java
                _language_ charted by<br>
                Project Valhalla.  (In this document, we use "currently"
                to describe the<br>
                language as it stands today, without value classes.)<br>
                <br>
                Valhalla started with the goal of providing
                user-programmable classes which can<br>
                be flat and dense in memory.  Numerics are one of the
                motivating use cases;<br>
                adding new primitive types directly to the language has
                a very high barrier.  As<br>
                we learned from [Growing a Language][growing] there are
                infinitely many numeric<br>
                types we might want to add to Java, but the proper way
                to do that is via<br>
                libraries, not as a language feature.<br>
                <br>
                ## Primitive and reference types in Java today<br>
                <br>
                Java currently has eight built-in primitive types. 
                Primitives represent pure<br>
                _values_; any `int` value of "3" is equivalent to, and
                indistinguishable from,<br>
                any other `int` value of "3".  Primitives are monolithic
                (their bits cannot be<br>
                addressed individually) and have no canonical location,
                and so are _freely<br>
                copyable_. With the exception of the unusual treatment
                of exotic floating point<br>
                values such as `NaN`, the `==` operator performs a
                _substitutibility test_ -- it<br>
                asks "are these two values the same value".<br>
                <br>
                Java also has _objects_, and each object has a unique
                _object identity_. Because<br>
                of identity, objects are not freely copyable; each
                object lives in exactly one<br>
                place at any given time, and to access its state we have
                to go to that place.<br>
                But we mostly don't notice this because objects are not
                manipulated or accessed<br>
                directly, but instead through _object references_. 
                Object references are also a<br>
                kind of value -- they encode the identity of the object
                to which they refer, and<br>
                the `==` operator on object references asks "do these
                two references refer to<br>
                the same object."  Accordingly, object _references_
                (like other values) can be<br>
                freely copied, but the objects they refer to cannot.  <br>
                <br>
                Primitives and objects differ in almost every
                conceivable way:<br>
                <br>
                | Primitives                                 |
                Objects                            |<br>
                | ------------------------------------------ |
                ---------------------------------- |<br>
                | No identity (pure values)                  |
                Identity                           |<br>
                | `==` compares values                       | `==`
                compares object identity      |<br>
                | Built-in                                   | Declared
                in classes                |<br>
                | No members (fields, methods, constructors) | Members
                (including mutable fields) |<br>
                | No supertypes or subtypes                  | Class and
                interface inheritance    |<br>
                | Accessed directly                          | Accessed
                via object references     |<br>
                | Not nullable                               |
                Nullable                           |<br>
                | Default value is zero                      | Default
                value is null              |<br>
                | Arrays are monomorphic                     | Arrays
                are covariant               |<br>
                | May tear under race                        |
                Initialization safety guarantees   |<br>
                | Have reference companions (boxes)          | Don't
                need reference companions    |<br>
                <br>
                The design of primitives represents various tradeoffs
                aimed at maximizing<br>
                performance and usability of the primtive types. 
                Reference types default to<br>
                `null`, meaning "referring to no object"; primitives
                default to a usable zero<br>
                value (which for most primitives is the additive
                identity).  Reference types<br>
                provide initialization safety guarantees against a
                certain category of data<br>
                races; primitives allow tearing under race for
                larger-than-32-bit values.  <br>
                We could characterize the design principles behind these
                tradeoffs are "make<br>
                objects safer, make primitives faster."<br>
                <br>
                The following figure illustrates the current universe of
                Java's types.  The<br>
                upper left quadrant is the built-in primitives; the rest
                of the space is<br>
                reference types.  In the upper-right, we have the
                abstract reference types --<br>
                abstract classes, interfaces, and `Object` (which,
                though concrete, acts more<br>
                like an interface than a concrete class).  The built-in
                primitives have wrappers<br>
                or boxes, which are reference types.<br>
                <br>
                <figure><br>
                  <a href="field-type-zoo.pdf" title="Click for
                PDF"><br>
                    <img src="field-type-zoo-old.png" alt="Current
                universe of Java field types"/><br>
                  </a><br>
                </figure><br>
                <br>
                Valhalla aims to unify primitives and objects in that
                they can both be<br>
                declared with classes, but maintains the special runtime
                characteristics<br>
                primitives have.  But while everyone likes the flatness
                and density that<br>
                user-definable value types promise, in some cases we
                want them to be more like<br>
                classical objects (nullable, non-tearable), and in other
                cases we want them to<br>
                be more like classical primitives (trading some safety
                for performance).  <br>
                <br>
                ## Value classes: separating references from identity<br>
                <br>
                Many of the impediments to optimization that Valhalla
                seeks to remove center<br>
                around _unwanted object identity_.  The primitive
                wrapper classes have identity,<br>
                but it is a purely accidental one.  Not only is it not
                directly useful, it can<br>
                be a source of bugs.  For example, due to caching,
                `Integer` can be accidentally<br>
                compared correctly with `==` just often enough that
                people keep doing it.<br>
                Similarly, [value-based classes][valuebased] such as
                `Optional` have no need for<br>
                identity, but pay the costs of having identity anyway.  <br>
                <br>
                Our first step is allowing class declarations to
                explicitly disavow identity, by<br>
                declaring themselves as _value classes_.  The instances
                of a value class are<br>
                called _value objects_.  <br>
                <br>
                ```<br>
                value class ArrayCursor<T> { <br>
                    T[] array;<br>
                    int offset;<br>
                <br>
                    public ArrayCursor(T[] array, int offset) { <br>
                        this.array = array;<br>
                        this.offset = offset;<br>
                    }<br>
                <br>
                    public boolean hasNext() { <br>
                        return offset < array.length;<br>
                    }<br>
                <br>
                    public T next() { <br>
                        return array[offset];<br>
                    }<br>
                <br>
                    public ArrayCursor<T> advance() { <br>
                        return new ArrayCursor(array, offset+1);<br>
                    }<br>
                }<br>
                ```<br>
                <br>
                This says that an `ArrayCursor` is a class whose
                instances have no identity --<br>
                that instead they have _value semantics_.  As a
                consequence, it must give up the<br>
                things that depend on identity; the class and its fields
                are implicitly final.  <br>
                <br>
                But, value classes are still classes, and can have most
                of the things classes<br>
                can have -- fields, methods, constructors, type
                parameters, superclasses (with<br>
                some restrictions), nested classes, class literals,
                interfaces, etc.  The<br>
                classes they can extend are restricted: `Object` or
                abstract classes with no<br>
                instance fields, empty no-arg constructor bodies, no
                other constructors, no instance<br>
                initializers, no synchronized methods, and whose
                superclasses all meet this same<br>
                set of conditions.  (`Number` meets these conditions.)<br>
                <br>
                Classes in Java give rise to types; the class
                `ArrayCursor` gives rise to a type<br>
                `ArrayCursor` (actually a parametric family of
                instantiations `ArrayCursor<T>`.)<br>
                `ArrayCursor` is still a reference type, just one whose
                references refer to<br>
                value objects rather than identity objects. For the
                types in the upper-right<br>
                quadrant of the diagram (interfaces, abstract classes,
                and `Object`), references<br>
                to these types might refer to either an identity object
                or a value object.<br>
                (Historically, JVMs were effectively forced to represent
                object references with<br>
                pointers; for references to value objects, JVMs now have
                more flexibility.)<br>
                <br>
                Because `ArrayCursor` is a reference type, it is
                nullable (because references<br>
                are nullable), its default value is null, and loads and
                stores of references are<br>
                atomic with respect to each other even in the presence
                of data races, providing<br>
                the initialization safety we are used to with classical
                objects.<br>
                <br>
                Because instances of `ArrayCursor` have value semantics,
                `==` compares by state<br>
                rather than identity.  This means that value objects,
                like primitives, are<br>
                _freely copyable_; we can explode them into their fields
                and re-aggregate them<br>
                into another value object, and we cannot tell the
                difference.  (Because they<br>
                have no identity, some identity-sensitive operations,
                such as synchronization,<br>
                are disallowed.)<br>
                <br>
                So far we've addressed the first two lines of the table
                of differences above;<br>
                rather than identity being a property of all object
                instances, classes can<br>
                decide whether their instances have identity or not.  By
                allowing classes that<br>
                don't need identity to exclude it, we free the runtime
                to make better layout and<br>
                compilation decisions -- and avoid a whole category of
                bugs.<br>
                <br>
                In looking at the code for `ArrayCursor`, we might
                mistakenly assume it will be<br>
                inefficient, as each loop iteration appears to allocate
                a new cursor:<br>
                <br>
                ```<br>
                for (ArrayCursor<T> c = Arrays.cursor(array); <br>
                     c.hasNext(); <br>
                     c = c.advance()) {<br>
                    // use c.next();<br>
                }<br>
                ```<br>
                <br>
                One should generally expect here that _no_ cursors are
                actually allocated.<br>
                Because an `ArrayCursor` is just its two fields, these
                fields will routinely get<br>
                scalarized and hoisted into registers, and the
                constructor call in `advance`<br>
                will typically compile down to incrementing one of these
                registers.<br>
                <br>
                ### Migration<br>
                <br>
                The JDK (as well as other libraries) has many
                [value-based classes][valuebased]<br>
                such as `Optional` and `LocalDateTime`.  Value-based
                classes adhere to the<br>
                semantic restrictions of value classes, but are still
                identity classes -- even<br>
                though they don't want to be.  Value-based classes can
                be migrated to true value<br>
                classes simply by redeclaring them as value classes,
                which is both source- and<br>
                binary-compatible.<br>
                <br>
                We plan to migrate many value-based classes in the JDK
                to value classes.<br>
                Additionally, the primitive wrappers can be migrated to
                value classes as well,<br>
                making the conversion between `int` and `Integer`
                cheaper; see the section<br>
                "Legacy Primitives" below.  (In some cases, this may be
                _behaviorally_<br>
                incompatible for code that synchronizes on the primitive
                wrappers.  [JEP<br>
                390][jep390] has supported both compile-time and runtime
                warnings for<br>
                synchronizing on primitive wrappers since Java 16.)  <br>
                <br>
                <figure><br>
                  <a href="field-type-zoo.pdf" title="Click for
                PDF"><br>
                    <img src="field-type-zoo-mid.png" alt="Java field
                types adding value classes"/><br>
                  </a><br>
                </figure><br>
                <br>
                ### Equality<br>
                <br>
                Earlier we said that `==` compares value objects by
                state rather than by<br>
                identity.  More precisely, two value objects are `==` if
                they are of the same<br>
                type, and each of their fields are pairwise equal, where
                equality is given by<br>
                `==` for primitives (except `float` and `double`, which
                are compared with<br>
                `Float::equals` and `Double::equals` to avoid
                anomalies), `==` for references to<br>
                identity objects, and recursively with `==` for
                references to value objects.  In<br>
                no case is a value object ever `==` to a reference to an
                identity object.<br>
                <br>
                ### Value records<br>
                <br>
                While records have a lot in common with value classes --
                they are final and<br>
                their fields are final -- they are still identity
                classes.  Records embody a<br>
                tradeoff: give up on decoupling the API from the
                representation, and in return<br>
                get various syntactic and semantic benefits.  Value
                classes embody another<br>
                tradeoff: give up identity, and get various semantic and
                performance benefits.<br>
                If we are willing to give up both, we can get both sets
                of benefits.  <br>
                <br>
                ```<br>
                value record NameAndScore(String name, int score) { }<br>
                ```<br>
                <br>
                Value records combine the data-carrier idiom of records
                with the improved <br>
                scalarization and flattening benefits of value classes.
                 <br>
                <br>
                In theory, it would be possible to apply `value` to
                certain enums as well, but<br>
                this is not currently possible because the
                `java.lang.Enum` base class that<br>
                enums extend do not meet the requirements for
                superclasses of value classes (it<br>
                has fields and non-empty constructors).<br>
                <br>
                ## Unboxing values for flatness and density<br>
                <br>
                Value classes shed object identity, gaining a host of
                performance and<br>
                predictability benefits in the process.  They are an
                ideal replacement for many<br>
                of today's value-based classes, fully preserving their
                semantics (except for the<br>
                accidental identity these classes never wanted).  But
                identity-free reference<br>
                types are only one point a spectrum of tradeoffs between
                abstraction and<br>
                performance, and other desired use cases -- such as
                numerics -- may want a<br>
                different set of tradeoffs.<br>
                <br>
                Reference types are nullable, and therefore must account
                for null somehow in<br>
                their representation, which may involve additional
                footprint.  Similarly, they<br>
                offer the initialization safety guarantees for final
                fields that we come to<br>
                expect from identity objects, which may entail limits on
                flatness.  For certain<br>
                use cases, it may be desire to additionally give up
                something else to make<br>
                further flatness and footprint gains -- and that
                something else is<br>
                reference-ness.<br>
                <br>
                The built-in primitives are best understood as _pairs_
                of types: a primitive<br>
                type (e.g., `int`) and its reference companion or box
                (`Integer`), with<br>
                conversions between the two (boxing and unboxing.)  We
                have both types because<br>
                the two have different characteristics.  Primitives are
                optimized for efficient<br>
                storage and access: they are not nullable, they tolerate
                uninitialized (zero)<br>
                values, and larger primitive types (`long`, `double`)
                may tear under racy<br>
                access.  References err on the side of safety and
                flexibility; they support<br>
                nullity, polymorphism, and offer initialization safety
                (freedom from tearing),<br>
                but by comparison to primitives, they pay a footprint
                and indirection cost.  <br>
                <br>
                For these reasons, value classes give rise to pairs of
                types as well: a<br>
                reference type and a _value companion type_.  We've seen
                the reference type so<br>
                far; for a value class `Point`, the reference type is
                called `Point`.  (The full<br>
                name for the reference type is `Point.ref`; `Point` is
                an alias for that.)  The<br>
                value companion type is called `Point.val`, and the two
                types have the same<br>
                conversions between them as primitives do today with
                their boxes.  (If we are<br>
                talking explicitly about the value companion type of a
                value class, we may<br>
                sometimes describe the corresponding reference type as
                its _reference<br>
                companion_.)<br>
                <br>
                ```<br>
                value class Point implements Serializable {<br>
                    int x;<br>
                    int y;<br>
                <br>
                    Point(int x, int y) { <br>
                        this.x = x;<br>
                        this.y = y;<br>
                    }<br>
                <br>
                    Point scale(int s) { <br>
                        return new Point(s*x, s*y);<br>
                    }<br>
                }<br>
                ```<br>
                <br>
                The default value of the value companion type is the one
                for which all fields<br>
                take on their default value; the default value of the
                reference type is, like<br>
                all reference types, null.  <br>
                <br>
                In our diagram, these new types show up as another
                entity that straddles the<br>
                line between primitives and identity-free references,
                alongside the legacy<br>
                primitives: <br>
                <br>
                ** UPDATE DIAGRAM **<br>
                <br>
                <figure><br>
                  <a href="field-type-zoo.pdf" title="Click for
                PDF"><br>
                    <img src="field-type-zoo-new.png" alt="Java field
                types with extended primitives"/><br>
                  </a><br>
                </figure><br>
                <br>
                ### Member access<br>
                <br>
                Both the reference and value companion types are seen to
                have the same instance<br>
                members.  Unlike today's primitives, value companion
                types can be used as<br>
                receivers to access fields and invoke methods, subject
                to accessibility<br>
                constraints: <br>
                <br>
                ```<br>
                Point.val p = new Point(1, 2);<br>
                assert p.x == 1;<br>
                <br>
                p = p.scale(2);<br>
                assert p.x == 2;<br>
                ```<br>
                <br>
                ### Polymorphism<br>
                <br>
                When we declare a class today, we set up a subtyping
                (is-a) relationship between<br>
                the declared class and its supertypes.  When we declare
                a value class, we set up<br>
                a subtyping relationship between the _reference type_
                and the declared<br>
                supertypes. This means that if we declare:<br>
                <br>
                ```<br>
                value class UnsignedShort extends Number <br>
                                          implements
                Comparable<UnsignedShort> { <br>
                   ...<br>
                }<br>
                ```<br>
                <br>
                then `UnsignedShort` is a subtype of `Number` and
                `Comparable<UnsignedShort>`,<br>
                and we can ask questions about subtyping using
                `instanceof` or pattern matching.<br>
                What happens if we ask such a question of the value
                companion type?<br>
                <br>
                ```<br>
                UnsignedShort.val us = ...<br>
                if (us instanceof Number) { ... }<br>
                ```<br>
                <br>
                Since subtyping is defined only on reference types, the
                `instanceof` operator<br>
                (and corresponding type patterns) will behave as if both
                sides were lifted to<br>
                the approrpriate reference type, and we can answer the
                question that way.  (This<br>
                may trigger fears of expensive boxing conversions, but
                in reality no actual<br>
                allocation will happen.)<br>
                <br>
                We introduce a new relationship based on `extends` /
                `implements` clauses, which<br>
                we'll call "extends"; we define `A extends B` as meaning
                `A <: B` when A is a<br>
                reference type, and `A.ref <: B` when A is a value
                companion type.  The<br>
                `instanceof` relation, reflection, and pattern matching
                are updated to use<br>
                "extends".<br>
                <br>
                ### Arrays<br>
                <br>
                Arrays of reference types are _covariant_; this means
                that if `A <: B`, then<br>
                `A[] <: B[]`.  This allows `Object[]` to be the "top
                array type", at least for<br>
                arrays of references.  But arrays of primitives are
                currently left out of this<br>
                story.   We can unify the treatment of arrays by
                defining array covariance over<br>
                the new "extends" relationship; if A extends B, then
                `A[] <: B[]`.  For a value<br>
                class P, `P.val[] <: P.ref[] <: Object[]`, finally
                making `Object[]` the top<br>
                type for all arrays.<br>
                <br>
                ### Equality<br>
                <br>
                Just as with `instanceof`, we define `==` on values by
                appealing to the<br>
                reference companion (though no actual boxing need
                occur).  Evaluating `a == b`,<br>
                where one or both operands are of a value companion
                type, can be defined as if<br>
                the operands are first converted to their corresponding
                reference type, and then<br>
                comparing the results.  This means that the following
                will succeed: <br>
                <br>
                ```<br>
                Point.val p = new Point(3, 4);<br>
                Point pr = p;<br>
                assert p == pr;<br>
                ```<br>
                <br>
                The base implementation of `Object::equals` delegates to
                `==`, which is a<br>
                suitable default for both reference and value classes.  <br>
                <br>
                ### Serialization<br>
                <br>
                If a value class implements `Serializable`, this is also
                really a statement<br>
                about the reference type.  Just as with other aspects
                described here,<br>
                serialization of value companions can be defined by
                converting to the<br>
                corresponding reference type and serializing that, and
                reversing the process at<br>
                deserialization time.<br>
                <br>
                Serialization currently uses object identity to preserve
                the topology of an<br>
                object graph.  This generalizes cleanly to objects
                without identity, because<br>
                `==` on value objects treats two identical copies of a
                value object as equal.  <br>
                So any observations we make about graph topology prior
                to serialization with<br>
                `==` are consistent with those after deserialization.<br>
                <br>
                ### Identity-sensitive operations<br>
                <br>
                Certain operations are currently defined in terms of
                object identity.  As we've<br>
                already seen, some of these, like equality, can be
                sensibly extended to cover<br>
                all instances.  Others, like synchronization, will
                become partial.  <br>
                Identity-sensitive operations include:<br>
                <br>
                  - **Equality.**  We extend `==` on references to
                include references to value<br>
                    objects.  Where it currently has a meaning, the new
                definition coincides<br>
                    with that meaning.<br>
                <br>
                  - **System::identityHashCode.**  The main use of
                `identityHashCode` is in the<br>
                    implementation of data structures such as
                `IdentityHashMap`.  We can extend<br>
                    `identityHashCode` in the same way we extend
                equality -- deriving a hash on<br>
                    primitive objects from the hash of all the fields.<br>
                <br>
                  - **Synchronization.**  This becomes a partial
                operation.  If we can<br>
                    statically detect that a synchronization will fail
                at runtime (including<br>
                    declaring a `synchronized` method in a value class),
                we can issue a<br>
                    compilation error; if not, attempts to lock on a
                value object results in<br>
                    `IllegalMonitorStateException`.  This is justifiable
                because it is<br>
                    intrinsically imprudent to lock on an object for
                which you do not have a<br>
                    clear understanding of its locking protocol; locking
                on an arbitrary<br>
                    `Object` or interface instance is doing exactly
                that.<br>
                <br>
                  - **Weak, soft, and phantom references.**  Capturing
                an exotic reference to a<br>
                    value object becomes a partial operation, as these
                are intrinsically tied to<br>
                    reachability (and hence to identity).  However, we
                will likely make<br>
                    enhancements to `WeakHashMap` to support mixed
                identity and value keys.  <br>
                <br>
                ### What about Object?<br>
                <br>
                The root class `Object` poses an unusual problem, in
                that every class must<br>
                extend it directly or indirectly, but it is also
                instantiable (non-abstract),<br>
                and its instances have identity -- it is common to use
                `new Object()` as a way<br>
                to obtain a new object identity for purposes of locking.
                 <br>
                <br>
                ## Why two types?<br>
                <br>
                It is sensible to ask: why do we need companion types at
                all?  This is analogous<br>
                to the need for boxes in 1995: we'd made one set of
                tradeoffs for primitives,<br>
                favoring performance (non-nullable, zero-default,
                tolerant of<br>
                non-initialization, tolerant of tearing under race,
                unrelated to `Object`), and<br>
                another for references, favoring flexibility and
                safety.  Most of the time, we<br>
                ignored the primitive wrapper classes, but sometimes we
                needed to temporarily<br>
                suppress one of these properties, such as when
                interoperating with code that<br>
                expects an `Object` or the ability to express "no
                value".  The reasons we needed<br>
                boxes in 1995 still apply today: sometimes we need the
                affordances of<br>
                references, and in those cases, we appeal to the
                reference companion.  <br>
                <br>
                Reasons we might want to use the reference companion
                include: <br>
                <br>
                 - **Interoperation with reference types.**  Value
                classes can implement<br>
                   interfaces and extend classes (including `Object` and
                some abstract classes),<br>
                   which means some class and interface types are going
                to be polymorphic over<br>
                   both identity and primitive objects.  This
                polymorphism is achieved through<br>
                   object references; a reference to `Object` may be a
                reference to an identity<br>
                   object, or a reference to a value object.  <br>
                <br>
                 - **Nullability.**  Nullability is an affordance of
                object _references_, not<br>
                   objects themselves.  Most of the time, it makes sense
                that primitive types<br>
                   are non-nullable (as the primitives are today), but
                there may be situations<br>
                   where null is a semantically important value.  Using
                the reference companion<br>
                   when nullability is required is semantically clear,
                and avoids the need to<br>
                   invent new sentinel values for "no value."<br>
                <br>
                   This need comes up when migrating existing classes;
                the method `Map::get`<br>
                   uses `null` to signal that the requested key was not
                present in the map. But,<br>
                   if the `V` parameter to `Map` is a primitive class,
                `null` is not a valid<br>
                   value.  We can capture the "`V` or null" requirement
                by changing the<br>
                   descriptor of `Map::get` to:<br>
                <br>
                   ```<br>
                   public V.ref get(K key);<br>
                   ```<br>
                <br>
                   where, whatever type `V` is instantiated as,
                `Map::get` returns the reference<br>
                   companion. (For a type `V` that already is a
                reference type, this is just `V`<br>
                   itself.) This captures the notion that the return
                type of `Map::get` will<br>
                   either be a reference to a `V`, or the `null`
                reference. (This is a<br>
                   compatible change, since both erase to the same
                thing.)<br>
                <br>
                <br>
                 - **Self-referential types.**  Some types may want to
                directly or indirectly<br>
                   refer to themselves, such as the "next" field in the
                node type of a linked<br>
                   list:<br>
                <br>
                   ```<br>
                   class Node<T> {<br>
                       T theValue;<br>
                       Node<T> nextNode;<br>
                   }<br>
                   ```<br>
                <br>
                   We might want to represent this as a value class, but
                if the type of<br>
                   `nextNode` were `Node.val<T>`, the layout of
                `Node` would be<br>
                   self-referential, since we would be trying to flatten
                a `Node` into its own<br>
                   layout. <br>
                <br>
                 - **Protection from tearing.**  For a value class with
                a non-atomic value<br>
                   companion type, we may want to use the reference
                companion in cases where we<br>
                   are concerned about tearing; because loads and stores
                of references are<br>
                   atomic, `P.ref` is immune to the tearing under race
                that `P.val` might be<br>
                   subject to.<br>
                <br>
                 - **Compatibility with existing boxing.**  Autoboxing
                is convenient, in that it<br>
                   lets us pass a primitive where a reference is
                required.  But boxing affects<br>
                   far more than assignment conversion; it also affects
                method overload<br>
                   selection.  The rules are designed to prefer
                overloads that require no<br>
                   conversions to those requiring boxing (or varargs)
                conversions.  Having both<br>
                   a value and reference type for every value class
                means that these rules can<br>
                   be cleanly and intuitively extended to cover value
                classes.<br>
                <br>
                ## Refining the value companion<br>
                <br>
                Value classes have several options for refining the
                behavior of the value<br>
                companion type and how they are exposed to clients.<br>
                <br>
                ### Classes with no good default value<br>
                <br>
                For a value class `C`, the default value of `C.ref` is
                the same as any other<br>
                reference type: `null`.  For the value companion type
                `C.val`, the default value<br>
                is the one where all of its fields are initialized to
                their default value.  <br>
                <br>
                The built-in primitives reflect the design assumption
                that zero is a reasonable<br>
                default.  The choice to use a zero default for
                uninitialized variables was one<br>
                of the central tradeoffs in the design of the built-in
                primitives.  It gives us<br>
                a usable initial value (most of the time), and requires
                less storage footprint<br>
                than a representation that supports null (`int` uses all
                2^32 of its bit<br>
                patterns, so a nullable `int` would have to either make
                some 32 bit signed<br>
                integers unrepresentable, or use a 33rd bit).  This was
                a reasonable tradeoff<br>
                for the built-in primitives, and is also a reasonable
                tradeoff for many (but not<br>
                all) other potential value classes (such as complex
                numbers, 2D points,<br>
                half-floats, etc).<br>
                <br>
                But for others potential value classes, such as
                `LocalDate`, there _is_ no<br>
                reasonable default.  If we choose to represent a date as
                the number of days<br>
                since some some epoch, there will invariably be bugs
                that stem from<br>
                uninitialized dates; we've all been mistakenly told by
                computers that something<br>
                will happen on or near 1 January 1970.  Even if we could
                choose a default other<br>
                than the zero representation, an uninitialized date is
                still likely to be an<br>
                error -- there simply is no good default date value.  <br>
                <br>
                For this reason, value classes have the choice of
                encapsulating or exposing<br>
                their value companion type.  If the class is willing to
                tolerate an<br>
                uninitialized (zero) value, it can freely share its
                `.val` companion with the<br>
                world; if uninitialized values are dangerous (such as
                for `LocalDate`), it can<br>
                be encapsulated to the class or package.  <br>
                <br>
                Encapsulation is accomplished using ordinary access
                control.  By default, the<br>
                value companion is `private`, and need not be declared
                explicitly; a class that<br>
                wishes to share its value companion can make it public:<br>
                <br>
                ```<br>
                public value record Complex(double real, double imag) {
                <br>
                    public value companion Complex.val;<br>
                }<br>
                ```<br>
                <br>
                ### Atomicity and tearing<br>
                <br>
                For the primitive types longer than 32 bits (long and
                double), it is not<br>
                guaranteed that reads and writes from different threads
                (without suitable<br>
                coordination) are atomic with respect to each other. 
                The result is that, if<br>
                accessed under data race, a long or double field or
                array element can be seen to<br>
                "tear", and a read might see the low 32 bits of one
                write and the high 32 bits<br>
                of another.  (Declaring the containing field `volatile`
                is sufficient to restore<br>
                atomicity, as is properly coordinating with locks or
                other concurrency control,<br>
                or not sharing across threads in the first place.)<br>
                <br>
                This was a pragmatic tradeoff given the hardware of the
                time; the cost of 64-bit<br>
                atomicity on 1995 hardware would have been prohibitive,
                and problems only arise<br>
                when the program already has data races -- and most
                numeric code deals with<br>
                thread-local data.  Just like with the tradeoff of nulls
                vs zeros, the design of<br>
                the built-in primitives permits tearing as part of a
                tradeoff between<br>
                performance and correctness, where primitives chose "as
                fast as possible" and<br>
                reference types chose more safety.<br>
                <br>
                Today, most JVMs give us atomic loads and stores of
                64-bit primitives, because<br>
                the hardware makes them cheap enough.  But value classes
                bring us back to<br>
                1995; atomic loads and stores of larger-than-64-bit
                values are still expensive<br>
                on many CPUs, leaving us with a choice of "make
                operations on primitives slower"<br>
                or permitting tearing when accessed under race.  <br>
                <br>
                It would not be wise for the language to select a
                one-size-fits-all policy about<br>
                tearing; choosing "no tearing" means that types like
                `Complex` are slower than<br>
                they need to be, even in a single-threaded program;
                choosing "tearing" means<br>
                that classes like `Range` can be seen to not exhibit
                invariants asserted by<br>
                their constructor.  Class authors have to choose, with
                full knowledge of their<br>
                domain, whether their types can tolerate tearing.  The
                default is no tearing<br>
                (safe by default); a class can opt for greater
                flattening at the cost of<br>
                potential tearing by declaring the value companion as
                `non-atomic`:<br>
                <br>
                ```<br>
                public value record Complex(double real, double imag) {
                <br>
                    public non-atomic value companion Complex.val;<br>
                }<br>
                ```<br>
                <br>
                For classes like `Complex`, all of whose bit patterns
                are valid, this is very<br>
                much like the choice around `long` in 1995.  For other
                classes that might have<br>
                nontrivial representational invariants, they likely want
                to stick to the default<br>
                of atomicity.  <br>
                <br>
                ## Migrating legacy primitives<br>
                <br>
                As part of generalizing primitives, we want to adjust
                the built-in primitives to<br>
                behave as consistently with value classes as possible. 
                While we can't change<br>
                the fact that `int`'s reference companion is the
                oddly-named `Integer`, we can give them<br>
                more uniform aliases (`int.ref` is an alias for
                `Integer`; `int` is an alias for<br>
                `Integer.val`) -- so that we can use a consistent rule
                for naming companions.<br>
                Similarly, we can extend member access to the legacy
                primitives, and allow<br>
                `int[]` to be a subtype of `Integer[]` (and therefore of
                `Object[]`.)<br>
                <br>
                We will redeclare `Integer` as a value class with a
                public value companion:<br>
                <br>
                ```<br>
                value class Integer { <br>
                    public value companion Integer.val;<br>
                <br>
                    // existing methods<br>
                }<br>
                ```<br>
                <br>
                where the type name `int` is an alias for
                `Integer.val`.  The primitive array<br>
                types will be retrofitted such that arrays of primitives
                are subtypes of arrays<br>
                of their boxes (`int[] <: Integer[]`).  <br>
                <br>
                ## Unifying primitives with classes<br>
                <br>
                Earlier, we had a chart of the differences between
                primitive and reference<br>
                types: <br>
                <br>
                | Primitives                                 |
                Objects                            |<br>
                | ------------------------------------------ |
                ---------------------------------- |<br>
                | No identity (pure values)                  |
                Identity                           |<br>
                | `==` compares values                       | `==`
                compares object identity      |<br>
                | Built-in                                   | Declared
                in classes                |<br>
                | No members (fields, methods, constructors) | Members
                (including mutable fields) |<br>
                | No supertypes or subtypes                  | Class and
                interface inheritance    |<br>
                | Accessed directly                          | Accessed
                via object references     |<br>
                | Not nullable                               |
                Nullable                           |<br>
                | Default value is zero                      | Default
                value is null              |<br>
                | Arrays are monomorphic                     | Arrays
                are covariant               |<br>
                | May tear under race                        |
                Initialization safety guarantees   |<br>
                | Have reference companions (boxes)          | Don't
                need reference companions    |<br>
                <br>
                The addition of value classes addresses many of these
                directly.  Rather than<br>
                saying "classes have identity, primitives do not", we
                make identity an optional<br>
                characteristic of classes (and derive equality semantics
                from that.)  Rather<br>
                than primitives being built in, we derive all types,
                including primitives, from<br>
                classes, and endow value companion types with the
                members and supertypes<br>
                declared with the value class.  Rather than having
                primitive arrays be<br>
                monomorphic, we make all arrays covariant under the
                `extends` relation.  <br>
                <br>
                The remaining differences now become differences between
                reference types and<br>
                value types:<br>
                <br>
                | Value types                                   |
                Reference types                  |<br>
                | --------------------------------------------- |
                -------------------------------- |<br>
                | Accessed directly                             |
                Accessed via object references   |<br>
                | Not nullable                                  |
                Nullable                         |<br>
                | Default value is zero                         |
                Default value is null            |<br>
                | May tear under race, if declared `non-atomic` |
                Initialization safety guarantees |<br>
                <br>
                <br>
                ### Choosing which to use<br>
                <br>
                How would we choose between declaring an identity class
                or a value class, and<br>
                the various options on value companiones?  Here are some
                quick rules of thumb: <br>
                <br>
                 - If you need mutability, subclassing, or aliasing,
                choose an identity class.  <br>
                 - If uninitialized (zero) values are unacceptable,
                choose a value class with <br>
                   the value companion encapsulated.  <br>
                 - If you have no cross-field invariants and are willing
                to tolerate tearing to<br>
                   enable more flattening, choose a value class with a
                non-atomic value<br>
                   companion.<br>
                <br>
                ## Summary<br>
                <br>
                Valhalla unifies, to the extent possible, primitives and
                objects.   The<br>
                following table summarizes the transition from the
                current world to Valhalla.<br>
                <br>
                | Current World                               |
                Valhalla                                                 
                |<br>
                | ------------------------------------------- |
                ---------------------------------------------------------
                |<br>
                | All objects have identity                   | Some
                objects have identity                                |<br>
                | Fixed, built-in set of primitives           |
                Open-ended set of primitives, declared via
                classes        |<br>
                | Primitives don't have methods or supertypes |
                Primitives are classes, with methods and
                supertypes       |<br>
                | Primitives have ad-hoc boxes                |
                Primitives have regularized reference
                companions          |<br>
                | Boxes have accidental identity              |
                Reference companions have no
                identity                     |<br>
                | Boxing and unboxing conversions             |
                Primitive reference and value conversions, but same
                rules |<br>
                | Primitive arrays are monomorphic            | All
                arrays are covariant                                  |<br>
                <br>
                <br>
                [valuebased]:
                <a class="moz-txt-link-freetext" href="https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html" target="_blank" moz-do-not-send="true">https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html</a><br>
                [growing]: <a class="moz-txt-link-freetext" href="https://urldefense.com/v3/__https://dl.acm.org/doi/abs/10.1145/1176617.1176621__;!!ACWV5N9M2RV99hQ!KmnfHlmDn7dP_Nxq9984m6AFRE5xDRQRRWsQk8BZgl_3-gKr0GCJd1nKDgbp4h_dnMfQHgY3Mr50rRd8HocG$" target="_blank" moz-do-not-send="true">https://dl.acm.org/doi/abs/10.1145/1176617.1176621</a><br>
                [jep390]: <a class="moz-txt-link-freetext" href="https://openjdk.java.net/jeps/390" target="_blank" moz-do-not-send="true">https://openjdk.java.net/jeps/390</a><br>
                <br>
              </font></font><br>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>