> On Jul 27, 2022, at 11:48 AM, Kevin Bourrillion <[email protected]> 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.)

Reply via email to