I like the concept of identity as akin to an extra field that only identity classes have, very much. It should feel like an "extra" feature, and purely behavioral in nature. That means I like to untie identity from addressability; push back on the idea that a reference encodes the object's identity in any way. It's instead some opaque "location" and we have no further expectations about it.

Let's run with this for a bit and see where it leads.  The following sketch is more of a "how we could describe it works" rather than a concrete proposal for refactoring the object model, but one can imagine an alternate universe where it actually was coded like this.

Imagine we have a magic class java.lang.Identity:

    final class Identity {
        /* Guaranteed to produce an Identity that is not equal() to any other known Identity */
        static Identity newIdentity();

        /* Special instance whose methods throw IMSE */
        static Identity NO_IDENTITY;

        void withLock(Runnable r) { ... }
        void wait() { ... }
        void notify() { ... }
    }

And every class (until now) has an invisible field:

    final Identity identity = Identity.newIdentity();

And == works by comparing all the fields (as per the Valhalla description), _including_ the identity field.  Since two "different" objects have different identities, they are never == (and the implementation can short-circuit.)  System::identityHashCode(o) is just `o.identity.hashCode()`, and Object::hashCode delegates to that just as Object::equals delegates to `==`.

Object methods can be redefined as:

    class Object {
        final Identity identity = Identity.newIdentity();

        void wait() { identity.wait(); }
        void notify() { identity.notify(); }
    }

and `synchronized (o) { block }` really means `o.identity.withLock(block)` (modulo exception transparency.)

Now, the main change for Valhalla is that instances of value classes, instead of having

    final Identity identity = Identity.newIdentity();

we have

    final Identity identity = Identity.NO_IDENTITY;


Can you think of any ways in which this is not isomorphic to the reality we have, other than assumptions about cost model?

Reply via email to