Queries regarding value classes
Quân Anh Mai
anhmdq at gmail.com
Tue Mar 15 04:03:48 UTC 2022
Hi,
>From a more implementation detailed point of view, the problem of whether
an object has an identity and the problem of whether it is stored as a
reference or not are orthogonal and lie at different levels of abstraction.
An object in memory is a representation of a Java object, so the identity
we are mentioning here is a property of the represented while reference is
a property of the representation. Normally, the identity of an object
forces this relation to be a 1-1 mapping so that we can keep the invariant
that all the representations of a single object behave consistently. For
value objects however, since the object does not imply identity, a single
Java object can have multiple representations (a value object can appear
simultaneously at various locations in the memory) without needing to do
some synchronisation, and since each portion of the program can have its
own representation of an object, it can do transformations on this version
(such as deconstructing into fields, throwing redundant elements) without
worrying about the behaviour of other parts of the program doing operations
on that same Java object, since they have their own versions of that object
to do so.
So in conclusion, they are orthogonal problems, a non-nullable primitive
object can still be implemented as a reference, it is solely the compiler
optimisation to deconstruct it into its fields, and the identitiless of the
Java object allows this transformation to be performed more safely and
consistently.
Hope you may understand better,
Quan Anh
On Tue, 15 Mar 2022 at 11:13, Julian Waters <tanksherman27 at gmail.com> wrote:
> So if I understand correctly, value objects are essentially the same as
> JEP-401's primitives but with nullability, and according to JEP-401,
> guarantee of atomic modification?
>
> "you are saying "change the a field of the object referred to by x to 3.""
>
> Regarding this earlier x.a = 3 example, if X was a good ol' identity
> object, x would then be a reference to the actual instance, and we'd simply
> follow the reference to where the actual object is stored and set a to 3.
> But if it was a value object, my understanding from your previous post is
> that it would be stored directly on the abstract (Ignoring HotSpot's actual
> complex implementation) stack to be operated on as a bunch of fields with
> no additional metadata other than the check for null. What's stopping us
> from then changing those fields directly? Like Quân Anh mentioned earlier,
> we would've effectively created a new object if we did do that, since a
> value object has no identity, but wouldn't we have technically changed the
> value of a after initialization? At the very least, I'd say it would be
> useful syntactic sugar to be able to do x.a on a value object instead of
> having to do new X(3); every time we wanted to change it, unless a is
> explicitly marked as final, without affecting == or related checks in any
> way, since (from what I know) value objects are compared by field with ==.
>
> Apologies for my lack of knowledge in this area, it still feels like I
> haven't really gotten a correct idea of what value types really are,
> especially compared to the true primitives of 401
>
> Thanks for the reply and have a great day!
>
> best regards,
> Julian
>
> On Tue, Mar 15, 2022 at 5:59 AM Brian Goetz <brian.goetz at oracle.com>
> wrote:
>
> > You are (understandably) conflating the properties of identity with the
> > properties of reference-ness.
> >
> > If you say
> >
> > x.a = 3
> >
> > you are saying "change the a field of the object referred to by x to 3."
> > The key to this sentence is *the object*; in order for assignment to make
> > sense, you have to know exactly which variable you are talking about.
> And
> > if that variable is an instance field, then you have to know exactly
> which
> > object it lives in. This is where identity comes in; if x is a reference
> > to an identity object, we then know how to find it. Which means, you
> need
> > an identity in order to be able to talk about mutability in a
> well-defined
> > way.
> >
> > So if that's true, what is a *reference* to a value? This is the
> > confusing part. If you think in terms of implementation, you'll probably
> > think "reference means pointer", which puts you into a C frame of mind,
> > because pointers always point at things. But that's not what reference
> > means in Java; its a more abstract kind of indirection.
> >
> > The distinction between int and Integer may be helpful. At one level,
> int
> > and Integer may seem like "almost the same sets of values"; the Integer
> > value set has one more value -- null -- than the int value set, and for
> > each of the other values, there is a bidirectional, 1:1 mapping between
> the
> > two value sets. But if we look closer, in fact these value sets are
> > disjoint! An int is not an Integer (even if they describe the same
> > number.)
> >
> > So one big difference between references and values is nullability; null
> > is a special kind of reference, the reference to no object at all.
> > Reference types can be null; primitive types cannot. (There's another,
> > even more subtle distinction, which is tearability, which comes from the
> > guarantees of the Java memory model.)
> >
> > If we have a value class:
> >
> > value class X { }
> >
> > this gives rise to a reference type X, whose values are references to
> > instances of X. But those instances do not have identity, which means we
> > can freely shred an X into the values of its fields, and later
> reconstitute
> > it into a new X, all without anyone noticing. That's what the lack of
> > identity enables. But the flip side of that means that any given X does
> > not "live" anywhere; it is just a loose aggregation field values, which
> > behaves like an object when called upon to do object-y things.
> >
> >
> >
> >
> >
> > On 3/13/2022 5:46 AM, Julian Waters wrote:
> >
> > Hi Quân Anh, thanks for the reply,
> >
> > I think I understand what you mean; Since value objects have no identity,
> > changing their fields would essentially mean the object is now entirely
> > different. However since that's the case, I'm still a little confused by
> > the semantics of what they really are. Specifically, most of their
> benefits
> > are centered around them being nothing more than their fields in memory,
> > but at the same time documentation states that they're referred to by
> > reference, which I find a little contradictory. If it's the former,
> they'd
> > be no different from primitives, and if the latter, they'd be the exact
> > same as identity objects, which has left me puzzled for quite some time.
> >
> > Sorry for all the trouble, have a great day
> >
> > best regards,
> > Julian
> >
> > On Sun, Mar 13, 2022 at 4:26 PM Quân Anh Mai <anhmdq at gmail.com> <
> anhmdq at gmail.com> wrote:
> >
> >
> > Hi,
> >
> > Regarding your concern of mutable value objects, having a mutable
> > identity-less object is illogical. Because a value class does not have a
> > unique identity, upon modification, the object is changed to become
> another
> > object. A value object is immutable in the same way that an int is
> > immutable. You can change a variable int a from containing a value of 3
> > to a value of 4, but you can’t change the number itself, it has been
> > mathematically and programmatically defined to be a specific bit
> sequence.
> > Similarly, you can change a variable Point a from enclosing the point (3,
> > 4) into the point (2, 5), but you can’t change the coordination of the
> > points themselves, they have been (in this case) also mathematically
> > defined. Your understanding of how value classes work is also not
> correct.
> > The fact that a value object can be deconstructed to its fields does not
> > mean that it will. This is simply an optimisation choice of the compiler.
> >
> > Regards,
> > Quan Anh
> >
> > On Sun, 13 Mar 2022 at 15:42, Julian Waters <tanksherman27 at gmail.com> <
> tanksherman27 at gmail.com>
> > wrote:
> >
> >
> > Hi all,
> >
> > I'd like to discuss several topics related to the current draft on value
> > classes.
> >
> > As mentioned in another post to this list at
> >
> https://mail.openjdk.java.net/pipermail/valhalla-dev/2022-January/009871.html
> > ,
> > currently value classes are specified as immutable, with all fields being
> > declared as final. If I understand this correctly, value based classes,
> > unlike the true primitives which work is currently focused on, can still
> > be
> > referred to by references; It is only identity that has been given up. In
> > that instance, naively speaking, wouldn't it be possible for value
> objects
> > to have mutable fields? In the same way that one can reference the
> fields,
> > one might possibly be able to also change their values through the
> > available object reference as well. From what I can tell, value objects
> > are
> > planned to work internally by decomposing them to nothing more than their
> > constituent fields and reconstructing them elsewhere. If that is the
> case,
> > shouldn't modification of their fields be possible? To me it seems the
> > modification would simply modify the copied value object *b *while
> leaving
> > original value object *a *unchanged, which sits perfectly with the
> > constraint that identity should not be supported. Am I mistaken in my
> > assumption?
> >
> > Additionally, if the above holds true, I also suggest allowing an object
> > to
> > be declared as value based at the site of their usage, instead of just at
> > their definition. Something like
> >
> > // Item is by default an identity class, but the field "item" here is now
> > // a value object due to the declaration of value
> > value Item item = new Item();
> >
> > would allow typical identity classes to be treated as value objects where
> > they're used. This would, to me, present a great deal of flexibility as
> > one
> > could then choose how to allocate a particular object without
> > constraining *every
> > *instance of that class to a specific value/identity dichotomy, and also
> > avoids the hassle of having to know which classes should be value or
> > identity types ahead of time. On a side note, the current proposal also
> > includes the ability to mark records as value based, given that records
> > are
> > meant exclusively as data classes, I suggest we flip that around and
> > instead have records as *value based by default, *and instead allow
> > marking
> > them as identity objects explicitly if required, with the currently used
> > ref keyword (Or whatever ref will eventually become), both at definition
> > and when an actual instance is constructed, as mentioned above. This
> could
> > save frustration from having to type value over and over whenever writing
> > the definition of a new record.
> >
> > Have a great day, hope I can hear your opinions on this! :)
> >
> > best regards,
> > Julian
> >
> >
> >
> >
>
More information about the valhalla-dev
mailing list