[External] : Re: Consolidating the user model

John Rose john.r.rose at oracle.com
Wed Nov 3 19:24:13 UTC 2021


On Nov 3, 2021, at 11:34 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> There's lots of great stuff on subtyping in chapters 15 and 16 of TAPL (esp 15.6, "Coercion semantics"), which might be helpful.  But as a tl;dr, I would suggest treating subtyping strictly as an is-a relation within our nominal type system.  By this interpretation, int <! long, and int <! Object; these are both _conversions_.  

Yes, that’s good.  So when someone tries to say “int <: long” or “int <: Object” our response would be “sorry, you are talking about a different idea of types”.  Something like “int <: Object” is a conversion the object can do, not two ways of viewing the whole object.  For us, types are about is-a, not is-a-member-of-larger-set (a disguised has-a) or can-do-a-conversion (another disguised has-a).

That does lead us to the next hard problem:  Which is that a value is not a box, it has a box.  And yet we want reflection (getClass specifically) not to make a distinction between those two distinct entities, but assign them the same class.  Which is fine, except that Classes have grabbed some of the jobs of types.

Brainstorming here:  We might be happier with a method called getRuntimeType which is allowed to return different values when applied to a box/ref of Point and a value of Point.  And then we notice that Point values don’t have inheritance or super types, directly, so the method paradigm (getRuntimeType being a method) is overkill; these are all statically bound methods.

And yet, there is a strong constraint that such a method, in its statically bound form, should return the same value as the corresponding call when applied to a box (under the type Object, maybe).  I don’t know how to untie this knot completely.

Brainstorming again:  getRuntimeType applied to a value can (and should?) be constant folded at compile time.  (Same point for getClass in fact.)  When applied to a ref it cannot (usually).  This makes getRuntimeType feel even less like an object method, but more like a __RuntimeTypeOf[ … ] syntax (no bikesheds were painted in the production of this statement).

I’m thinking that those few users who want to extract type mirrors from (non-null) witnesses will need to specify manually which type projection they are expecting, rather than hope that the the result they want will pop out.

Not this:
  Class<Point> cp = point.getClass(); //Point
  Class<Point> ci = anint.getClass(); //Integer (aka int.ref)

but this:
  Class<Point> cp = point.getClass().valueType(); //Point
  Class<Point> ci = anint.getClass().valueType(); //int

or else this:
  Class<Point> cp = point.getClass().referenceType(); //Point.ref
  Class<Point> ci = anint.getClass().referenceType(); //Integer

In other words, if the rift between Integer and Point is not completely healed, users can probably work around the problems.



More information about the valhalla-spec-observers mailing list