RefObject and ValObject

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Apr 15 11:02:18 UTC 2019


The gordian knot here is that whenever you see Object as part of a 
*type* you'd like to interpret it as a top type (the root of the 
hierarchy). OTOH, when you see Object as part of an *expression* you'd 
like to interpret it as something else (e.g. RefObject). And there are 
also things in between - e.g. Object.class, where it's not uber clear 
whether you want one or the other, but let's not get too distracted by 
these for the moment.

 From a type-system perspective, the basic property called 
_preservation_ mandate (Gavin, correct me if I'm wrong :-)) that, given 
an expression of *static type* E, the type associated with the value V 
obtained by executing the expression must be a subtype of E, which we 
can write:

typeof(V) <: E

(of course this is only true for type systems which feature subtyping, 
otherwise typeof(V) == E).

So, in our case, the theorem demands something like this:

typeof(new Object()) <: Object

But it seems like we have already ruled this out - since, if typeof(new 
Object()) is 'RefObject', you don't want RefObject <: Object.

So, from a type-system perspective, we're on unsound territory, at least 
assuming we only use classes w/ single inheritance.

Interfaces (or, more generally, multiple inheritance) add a bit of 
flexibility because (as Brian said) we could say:

typeof(new Object()) = XYZ, where XYZ <: RefObject && XYZ <: Object

So this would satisfy the type theory; whether it can be made into 
something that looks compelling for a Java user, that's another story. 
Note that the dual nature of *type* vs. *expression* mentioned at the 
beginning will bite you as soon as you start doing things like this:

void m(RefObject ro) { ... }

m(new Object()) // ok, as per above
m((Object)new Object()) // not ok?
m(Object.class.newInstance()) // WAT!?

Maurizio

On 08/04/2019 20:58, Brian Goetz wrote:
> No matter which way we go, we end up with an odd anomaly: “new Object()” should yield an instance of RefObject, but we don’t want Object <: RefObject for obvious reasons.  Its possible that “new Object()” could result in an instance of a_species_  of Object that implement RefObject… but our theory of species doesn’t quite go there and it seems a little silly to add new requirements just for this.


More information about the valhalla-spec-observers mailing list