Question about universal type variables
Brian Goetz
brian.goetz at oracle.com
Wed Jul 27 19:22:51 UTC 2022
> 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220727/b0239e6d/attachment.htm>
More information about the valhalla-spec-observers
mailing list