where are all the objects?
Kevin Bourrillion
kevinb at google.com
Thu Jul 14 16:48:00 UTC 2022
You knew you could count on me. :-)
On Wed, Jul 13, 2022 at 1:54 PM John Rose <john.r.rose at oracle.com> wrote:
> On 13 Jul 2022, at 13:23, John Rose wrote:
>
> …Another result of backing away from “primitive” is that we have to engage
> with the question of “where are the objects?” Obviously every non-null
> value of a variable whose type is an identity class refers to “an object”.
> But beyond that it gets dicey and we will have to adjust our agreements, I
> think. This is probably worth a separate thread, which I will start, and
> which I expect Kevin will be very interested in.
>
> A class defines ways to “realize” the class in its types, that is, in
> variables of its companion types.
>
Aside: I'd push back on the term "companion types of a class"; the class
*defined* those types so they are just its "defined types".
I do like calling the value type a "companion type to the reference type"
(not to the class) well enough, though. For a couple reasons -- there is
the parallel relationship of equals that I expect "companions" to have, and
it's injecting a new term for a new concept, which is easier for folks to
swallow than "we need a new term for an old concept while we are
simultaneously injecting new concepts too".
Examples: C r = new C(); and C.val v = C.default; and new C.val[1].
>
> (For class declared non-atomic, races can also “realize” values of the
> class.)
>
> I’m using a more neutral term “realize” instead of “instantiate”. You can
> think “instantiate” or “construct” if you like. A long-winded way to say
> “realize a class” without tripping over words I want to avoid is “make a
> non-null runtime configuration of a variable of a type of that class,
> using, directly or indirectly, an expression allowed by the declaration of
> that class”.
>
Fair enough; I'm viewing this roughly as "originating (summoning,
conjuring) an instance of the type", as distinct from "being handed it from
somewhere".
I think we are more precisely talking about "realizing the *type*", and
"realizing the class" is a shorthand for "realizing one of the types
defined by the class". It seems too ambiguous to focus on "realizing the
class".
These propositions seem to be all true (“at least” in part):
>
> - The result of realizing at least some classes in some types is, in
> fact, an “object”.
> - The result of realizing at least some classes in some types is, in
> fact, an “instance” of that class.
> - The result of realizing at least some classes in a value type is a
> “value” of that class.
>
> My model sees this instead as:
The instances of a value type are "values".
The instances of a reference type are "references to objects".
The result of realizing a type will always be an instance of that type by
definition.
The "instances of a class" is a slightly more problematic phrase I'd rather
avoid.
(Of course, I say this to suggest that I think the differences are
important.)
> - Every variable “has a value”.
> - Every reference, other than null, “refers to an object”.
>
> (imho we would do well to shift to "null *isn't* a reference, but the
lack of a reference where a reference could be". It lacks the most basic
and important capability all references have: the ability to be
dereferenced. But I understand that may be a big change, and not
necessarily supported by theory.)
>
> - Every non-reference variable “contains a value” (as well as having
> it).
>
> Fair enough. I won't go into the subtle reasons why I use "remembers a
value" over "contains a value".
>
>
> So, do we think they are true? And of which classes, and for which of
> their companion types, are they true?
>
> I think some of us would like to reserve the term “object” for something
> that has a header and a storage block in the heap. Although talking about
> memory blocks and headers and machine pointers is probably illegitimate for
> a JVMS, it is semi-transparent enough to “see” that stuff like that is
> going on. (Except when it isn’t: Both Valhalla flattened references and
> classic escape analysis break those intuitions.) Users will want
> *something* to visualize about objects, and maybe that just doesn’t jibe
> with how we want them to think about values.
>
Heh, yes, I've been pretty determined about this. I see a beautifully clean
distinction between objects and values, that I would feel grief at losing:
An object A value
----------------------------- -----------------------------------------
has independent existence is ephemeral (no existence of its *own*)
is self-describing is context-described
is accessed via reference is used directly
is eligible to have identity can’t have identity
is polymorphic is strictly monomorphic
has the type `Object` does not have the type `Object`
If we let values of value types (i.e., all values except references and
null) become "objects" too, then we will need a term for what used to mean
"object" above. For me it is hard to see that ending up in a smooth and
shiny place.
OTOH, it is really freeing to be able to say that “every class makes
> objects”, and build from there into a world of “identity objects” and
> “value objects”.
>
But, in this lexicon, "value objects" becomes ambiguous between (what we'd
been calling) bucket 2 and bucket 3.
In the model I've been advocating we have: "the instances of identity
classes are identity objects; the instances of value classes are either
value objects or just (composite) values." This brought me rare feelings
of terminological victory, the kind of clarity you hope to be able to
achieve but almost never can. Granted, it's still got to be carefully
taught to everyone, against some amount of resistance, but that's true no
matter what lexicon we adopt. Some old associations will *have* to be
broken.
(I can also appeal to various C standards, in which everything is either an
> object or a function. Yes, a C int is a C object. Take that, Mr.
> Objects-Are-Everywhere Java. That might work for us too with minor
> adjustments.)
>
> Even if we give up on making everything an object, I will still request
> that we cling to *some* word that can uniformly be applied to the result
> of realizing *any Java class*. If that word is not “object” I think it is
> “instance”.
>
Yes, I think it is absolutely and usefully "instance".
And all instances except arrays (ugh, let's dodge whether null is an
instance) are more specifically *class instances*, and that's what gives us
instance members. I believe *that* is the unification we've really been
driving for when we've said words like "we want to make everything an
object".
> Also I think it is still useful to at least pretend (virtually) that a
> reference is always to an object. So, something like this:
>
> -
>
> The result of realizing any class in its reference companion is an
> object of that class.
> -
>
> The result of realizing any class into any of its companion types is
> an instance of that class.
> -
>
> The result of realizing any value class into its value companion is a
> “value” of that class.
> -
>
> Maybe also: The result of realizing any value class into its reference
> companion is a “value” of that class (as well a an “object” of that class).
>
> I would say no to this: a "value object" is not a "value". That takes
explaining/apologetics, of course, so I don't love the term "value object"
for that reason, but have no *other* complaint about it and can live with
it. "identityless object" is just too unwieldy.
>
> -
>
> Every variable “has a value”. (Same as above.)
> -
>
> Every reference, other than null, “refers to an object”. (Same as
> above.)
> -
>
> Every non-reference variable “contains a primitive” or “contains an
> instance”.
>
> But primitive values are instances too. Of primitive types. I think that
has always been true (though most of us aren't in the habit of saying it,
because they were never *class instances* which is a very useful kind).
Soon it will be "even more true" as they also even become *class* instances.
> -
>
> Any value is (therefore) either a primitive, an instance, a null
> reference, or a reference to an object.
>
> I think "instance" is awkwardly standing in for something more specific,
here. I think I'd say "a value is either an instance of a value type (such
as a primitive type), a reference to an object, or the null reference".
> -
>
> An object (therefore) is an instance or an array. (Cribbing from Kevin
> here.)
>
> I would say that arrays are also instances -- of array types. What they
aren't is *class* instances. (So they don't get to have members; `length`
and `clone` are at best half-heartedly-simulated members.)
A tough spot about my model (which I think is unavoidable/acceptable) is
that I can't get away with saying "An object is any class instance or
array" anymore. Because Long is a class, it defines two types, and both
those types have instances, and all those instances deserve equally to be
considered "instances of the class". So the term "class instance" becomes
inclusive of `(int) 42` which is so not an object.
> -
>
> By an abuse of language, it is common to ignore the reference part of
> a reference variable, and say that it “has” or “contains” an instance if
> not null. (This makes opportunities for consistent reasoning about
> C.ref and C.val variables.)
>
> Yeah, since the language and runtime abstract references away from us,
traversing them for us when needed, we naturally also abstract them away
from our speech and thoughts much of the time. I'm okay with "has an
instance" but "contains an instance" is the kind of phrase I'd gently push
back on, because it's tantamount to "the instance is contained by".
--
Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at google.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220714/979071f9/attachment-0001.htm>
More information about the valhalla-spec-observers
mailing list