My (limited) understanding is:

a) The first goal is just to enable a type parameter to accept both reftypes and valtypes as type arguments (making it a "universal" type parameter or UTP, and making the type variable it defines for use inside that scope a UTV).

b) Goals to follow would do progressively more efficient things when the type arguments are valtypes. I'd expect that optimal performance demands dynamically generating customized versions of the class in some manner (which I'd further expect is fair to call "templating"?).

For starters, does the above seem accurate and well-stated?

Correct.  We envision two phases, like your (a) and (b), where the first is an erasure-based, language-based system which conforms to the behavior that the VM-based specialization would offer, allowing specialization to be viewed as a pure optimization, rather than an actual language feature.

The main question of this email is: if T is a universal type variable, then /what kind of type/ is that? Is it a reftype, a valtype, or something else?

It is a type of indeterminate ref-ness or val-ness.  This will have both restrict some old behavior and provide some new behavior.  For example:

    T t = null;

will generate an unchecked warning, since we can't be sure we're not polluting the heap with nulls.  (Null pollution is a straightforward special case of heap pollution.)  On the other hand, you'll be able to use the new derived type `T.ref`, which would mean "T if its already a ref, or the ref companion if T is a val."  This allows Map::get to be rescued:

    V.ref get(K k);

If we follow these models where they lead they seem to suggest two different answers for my question (i.e.,"if T is a UTV, what kind of type is that?"):

Model 1: Since the UTV type represents or "stands in for" future type arguments which might be of either kind -- and note that it does behave differently from any regular reftype or valtype, being sort of quasi-nullable -- we are forced to conclude that it will be a third kind of type, a "universal" type. So the Java type system ends up tripartite after all. And, what is a value of this type?    * The values-are-not-objects model stammers, "you've got a class instance for sure, but it might ambiguously be a value or a reference to an object, and often that doesn't matter".    * The values-are-objects model stammers, "you've got an object for sure, all you don't know is the 'placement' of the object, direct or indirected, and often that doesn't matter".

So, note that in a generic class today, there's no way to "summon" any value of T *except null*.  You can't say `new T()` or `new T[3]` or `T.class.newInstance()`.  The values of T (except null) always come from *outside the house*, and their T-ness is backed up by synthetic casts (modulo heap pollution).  An ArrayList<T> starts out empty, then someone puts T's in it, at which point the ArrayList can turn around and hand those Ts back.  But it can't make any new Ts.  All it needs to know is that T is layout-compatible with the layout of the bound.

Reply via email to