Question about universal type variables
Remi Forax
forax at univ-mlv.fr
Wed Jul 27 22:48:35 UTC 2022
----- Original Message -----
> From: "daniel smith" <daniel.smith at oracle.com>
> To: "Kevin Bourrillion" <kevinb at google.com>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Sent: Thursday, July 28, 2022 12:25:15 AM
> Subject: Re: Question about universal type variables
>> On Jul 27, 2022, at 11:48 AM, Kevin Bourrillion <kevinb at google.com> wrote:
>>
>> 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?
>>
>> I can see two main options for how to answer that, which I think follow
>> naturally from the two already-existing models for how developers might
>> conceptualize type variables.
>>
>> These existing models, first:
>>
>> Model 1: A type variable is a mere placeholder that "will be" some other type
>> later. When you interact with it, you're "really" interacting with the future
>> type argument. If asked a question like "is an `E` inside `class ArrayList<E>`
>> a `Number`?" this model would say "well, it might be or it might not be".
>>
>> Model 2: A type variable is a bona fide local type in its own right. It is or
>> becomes no other type but itself. Its simple job is just to enforce whatever
>> restrictions it needs to in order to preserve its substitutability for any type
>> argument in-bounds. If asked the same question as above, "is an `E` inside
>> `class ArrayList<E>` a `Number`?" this model would say "no, it is certainly
>> not, but it does guarantee to be substitutable for `Number`, among other
>> types."
>>
>> I would describe Model 2 as being close to the JLS view of the world, but in a
>> way, Model 1 is the very illusion that Model 2 is working to create. I
>> certainly expect the majority of developers think like Model 1 most of the
>> time, and most of the time it's okay.
>
> I'm not *totally* sure I grasp all the differences, but here are a couple of
> observations that seem to support Model 2:
>
> - At compile time, type checking, overload resolution, etc., is performed with
> respect to a single type variable type, not some sort of "for all possible
> types..." analysis. If you invoke a method on an interface bound, you're really
> invoking that method of the interface, not (directly) whatever method gets
> implemented by an instantiation of the type variable.
>
> - At run time, the code is executed in terms of a single runtime type (the
> erased bound). Specialization, a JVM concept, may allow different species to
> carry different "type restrictions" attached to their parameter types, but
> those type restrictions *add* type information, they don't *contradict* type
> information. If the descriptor says LObject, a type restriction might say "this
> is an LObject that is known to be convertible to QPoint", but it won't say
> "instead of an LObject, this is actually a QPoint". (I'm muddling language and
> JVM models here, but you get the idea: generic code is executed generically.)
For the runtime part, there are also operations (opcodes) that will do something different depending on the type argument (or a type derived from the type argument),
by example, creating an array, instantiating a generic, asking for a default value at runtime returns different values depending on the type argument at runtime.
The types restrictions are one of those operations which are expressed as an attribute instead of as an opcode because it also helps the calling convention (monomorphization),
but at runtime a type restriction will do a checkcast (or an asType (or an explicitCast)) depending on the type argument,
Rémi
More information about the valhalla-spec-observers
mailing list