Of course something will have to change, and we want that change
    to feel natural and not pulling the rug out from under user's
    mental models.

    The change I'm proposing in this model is:

    Instead of values being "primitives and object references", values
    become "value objects and object references".  A Complex.val is a
    value.  3+2i still meets all the requirements of values: free
    floating, no canonical location, no identity, immutable.  It's
    just a "bigger" value that we could have before. Primitives become
    value objects.  I think people can understand (and will like) this
    story.

    Variables and containers are unchanged.

    Objects are instances of classes.  Instances of identity classes
    remain dependent on references to interact with them; instances of
    value classes can also be the target of references, *and* are
    values on their own.  (This is not excessively weird, since
    "Complex" and "reference to Complex" is like `int` and `int *` in C.)


It's a familiar aspect of C that Java quite distinctly distanced itself from!

Agreed, and I do feel a little dirty for making the comparison, as we have gotten so far without having to understand the distinction between `int` and `int *`.  But only a little dirty, because if you want to ignore the difference, you can -- and if you want to understand the difference there is a pretty clear foundation for it.

Further, in my defense, we have been playing a kind of interesting trick since the beginning.  Arguably, Java has *never* had objects -- only object references!  You can't denote "reference to X" in the type system; some times are just reference types.  And there is no expression whose type is any kind of object; only references to objects.  The dot operator does some sort of quantum tunneling to access the object state, and bring it back into the program, as if by magic.  The Java 1.0 version of your question is: where are *any* of the objects?

So you could describe my "VAO" position as "finally, you can touch some of the objects" (we always knew they were in there somewhere!) The identity objects are still as hidden away as ever, but the value objects will come out and play, and in fact the legacy primitives are revealed to have been "bare" objects all along!   And the box types were a clunky way to say "reference to value object", which we've now declunkified.

Where I see your discomfort is the "a value object can be a value *or* a referent, dealer's choice."  That is indeed new and confusing.  My claim is that this (a) really describes what is going on, (b) is a clean generalization of the primitives-and-references we have now, (c) allows the primitives to become real objects, and (d) once you internalize this "value or referent" duality, the rest comes along easily.  So maybe I've just made my peace with this, because I like the properties it gives me.



    Let's take a look at your essential characteristics of objects again.

     - Objects are entities, they have their own independent
    existence.  I think this one is a consequence of "objects only can
    be interacted with through references."  That is, there is a kind
    of value called "reference to object", and the reference refers to
    ... an object, which is a thing separate from the reference.

    So, *if* an object is the target of a reference, then yes, it must
    be an entity that is somewhere else, with its independent
    existence.  "Thing that is the target of an object reference" is
    one reasonable definition for "Object", but I don't think it is
    the only one. What I'm saying is that I think its fair to say an
    instance of Complex is an object (and further, that saying "its an
    instance, but not an object", is likely to be more confusing that
    beneficial.)



Two possible directions of that confusion:

1. But why is it not an object? The big problem here, raised by John I think, is "Java is an object-oriented language". Uh oh. That certainly does demand the expansive notion of "object"; I have to concede that point. On the other hand, maybe, Java did then put that theory into practice using terms like "instance member", not "object member". It also created a class called "Object" and attached a bunch of specific ideas to that, only 3.5 of which are really general to all instances.

2. Okay but then why is it still an instance? Here we'd be asking users to shed some of the baggage they've (incidentally) attached to "instance" in the past, realizing that that baggage actually belonged with "object". What remains with "instance" is the essential stuff: instance members, instance state.

The intuition I think users already have, and which we can double down on, is that classes are like templates for stamping out objects/instances.  The user declares the class with its name, supertypes, members, etc, and then can make many instances from the template.  So anything that says "instance, but not object" seems needlessly confusing, because it breaks an existing intuition that is working fine, for little benefit (that I can see.)

The use of object and instance to mean the same thing has an understandable historical context.  In the late 80s/early 90s, object orientation was an abstract concept; objects are stateful, independent entities that communicate by message passing.  (Kay's objects were more like Erlang's actors than Java/C++ classes.)  Java (and other languages) interpreted OO through the lens of classes, which have instances.  So this is really like "class-oriented-language implements object-oriented-language", where we say "class instances are what we mean by objects."  But, this is historical path-weaving; objects == instances seems like a sleeping dog that should be let lie, because the cost of changing perception seems way higher than the value of doing so.


      I think the term for what you are describing is *referent*, and
    not all objects are referents.



I agree that "referent" is another reasonable choice of term for what the doc calls "object". I think it beats "heap object". But I think it has serious problems (below).


      Here, I say that objects remain self-describing under the
    "instances are objects" model, but something interesting happens
    under the hood about *where* the description lives.  If I have a
    `Complex` in a variable of type `Complex.val`, there is sufficient
    information *in the container* to know the class of the instance,
    so the instance doesn't have to carry it with it.  There is an
    operation for "take a reference of" that can be applied to value
    objects.  This operation (logically, though this is frequently
    optimized away) takes that information out of the container and
    puts it in an object header.  But regardless of whether the
    typestate is in the container or the object itself, objects are
    self-describing.



I think this paragraph is merely asking for a different term/definition from the "self-describing" term I'm using and doesn't say anything deeper than that. Maybe there is a better term. I used "self-describing" partly because I thought it has a healthy existing connotation that the data itself is bloated with all that description. e.g. Java serialized forms are self-describing (setting aside all the ways that description can fail).

OK, I think I see what you're getting at.  I'm focusing on "self-describing" as "can it answer the question".  (Today, `int` is arguably not self-describing by this description, because you can't ask it any questions, though that will change.)  You're taking self-describing to mean the cost of stapling an object header to the payload.  (Which is implicitly one of those "box and pointer" perspectives that John talked about, which on the one hand is useful for building intuitions, but on the other can build wrong intuitions.)


     - An object is always accessed by reference.  This is what I'm
    saying changes; value objects are values. So I think that what you
    are describing as essential characteristics of objects, are really
    essential characteristics of *referents of object references*. And
    I would argue that while this is a well-defined concept, it's not
    the most important distinction we want to put in the user's face. 
    Instead, we can say that an instance of Complex can be a value, or
    it can be a referent, but its the same Complex either way, and the
    user gets to decide what packaging it wants to put it in.



I think the key thing to notice about "referent" is that it's a role noun (I don't know what grammarians would call it), like "pedestrian" or "projectile". That is, it doesn't seem to be saying anything at all about the thing itself, only about the role that thing is currently playing in some broader relationship or activity.

Yes!  Which is in line with the fact that we blur the distinction between reference and referent today, and we will continue to blur it tomorrow.  And whether a value is a value object or an object reference is steered by types -- whether the types are value types or reference types.  But one reason to push this "its the same instance either way", is that it goes a ways towards busting the existing concept of boxing.  The existing concept of boxing appeals to "construct a new box" and "unpack the value from the box", which (a) sounds like a lot of motion (it is) and (b) says that the primitive and the box are totally different kinds of things. Whereas the "value object vs referent" encourages a model of "its the same thing all along, we are just holding it differently."  Bare hands vs tongs, if you will.

Are we getting any closer, or just digging in?

Reply via email to