<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4"><font face="monospace">You posted this earlier, but I
was kind of at a loss for how to respond, because it reads to me
like "why don't we 'just' reify generics", as if we were just
waiting for someone to come up with the idea of reification. I
think you are underestimating the scope of what you are
suggesting by several orders of magnitude. <br>
<br>
Reification is invasive. You would have to plumb new data paths
in method calling conventions to pass type witnesses through
generic methods (so when someone says `new Foo<T>`, where
T is a method type variable, you know what T is), and through
object layout in the heap (so when someone asks a List what it
is a List of, it can find out), and through reflection, and
through serialization, and ... And even if you did that, you
might discover that some runtime typechecking that you'd like to
do is undecideable (see e.g.
<a class="moz-txt-link-freetext" href="https://www.researchgate.net/publication/303969346_On_Decidability_of_Nominal_Subtyping_with_Variance">https://www.researchgate.net/publication/303969346_On_Decidability_of_Nominal_Subtyping_with_Variance</a>).
<br>
<br>
The mechanics of reification are well enough understood; see
e.g. the Kennedy and Syme paper of how they did it in .NET
(<a class="moz-txt-link-freetext" href="https://www.microsoft.com/en-us/research/publication/design-and-implementation-of-generics-for-the-net-common-language-runtime/">https://www.microsoft.com/en-us/research/publication/design-and-implementation-of-generics-for-the-net-common-language-runtime/</a>),
or Maurizio Cimadamore's PhD thesis. But in addition to the
substantial re-architecting of the VM that is required here, you
also have to face the problem of migration compatibility. A key
requirement when we did generics is that libraries and clients
could be generified independently; if you generify a library,
its clients can upgrade to generics now, later, or never, at
their choice. When .NET chose heterogeneous translation over
homogeneous, they had to write new collection libraries. (That
was OK because they had relatively few users at the time; Java
does not have this luxury.) <br>
<br>
This is not a "why don't you just" problem. <br>
<br>
Several thousands of expert-hours have already gone into
researching how these things could be achieved; the best
capturing so far is John's discussion of the "Parametric VM",
which is still in the "working out the ideas" stage. You can
read the current state here:<br>
<br>
<a class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/~jrose/values/parametric-vm.pdf">http://cr.openjdk.java.net/~jrose/values/parametric-vm.pdf</a><br>
<br>
There's a ton there, and a ton left to go.<br>
<br>
<br>
<br>
</font></font><br>
<div class="moz-cite-prefix">On 12/4/2022 4:06 AM, Red IO wrote:<br>
</div>
<blockquote type="cite" cite="mid:CABKyW1vpkOau==r_wRxaXNhH0OT5Djh2DtVC-x4Aa1gqDLKYWg@mail.gmail.com">
<div dir="auto">
<div dir="auto"><br>
</div>
<div dir="auto">I was once again writing some generic Java class
and suddenly I stand there again, I could not get the type of
T.</div>
<div dir="auto"><br>
</div>
<div dir="auto">I’m sure this scenario sound familiar to every
Java developer out there.</div>
<div dir="auto"><br>
</div>
<div dir="auto">If you first stumble across this problem type
erasure comes up as the culprit: “Type T is not there at
runtime it is replaced with Object”</div>
<div dir="auto"><br>
</div>
<div dir="auto">There are many solutions to this problem some
hacky some require braking change to the generic system.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Now my idea was why don’t we trace back the
types at compile time? I mean every generic class is
constructed somewhere in 6 possible ways:</div>
<div dir="auto"><br>
</div>
<div dir="auto">Foo<String> foo = new Foo<>();</div>
<div dir="auto">Foo<T> foo2 = new Foo<>();</div>
<div dir="auto">Foo foo3 = new Foo();</div>
<div dir="auto">Foo<?> foo4 = new Foo<>();</div>
<div dir="auto">Foo<? extends String> foo5 = new
Foo<>();</div>
<div dir="auto">Foo<? super String> foo6 = new
Foo<>();</div>
<div dir="auto">In case 1 we are already at our destination. The
code the compiler gets contains the information we want. Why
don’t we attach the type written in plain sight to the generic
constructor?</div>
<div dir="auto"><br>
</div>
<div dir="auto">Like an implicit Foo<String> foo = new
Foo<>(java.lang.String.class); (which explicitly is a
current way of solving this. Which is in my opinion pretty
ugly.)</div>
<div dir="auto"><br>
</div>
<div dir="auto">It would be syntactic sugar for the syntax above
which spares the developers of repeating themselves. (just
like <> does)</div>
<div dir="auto"><br>
</div>
<div dir="auto">If the compiler would just use the information
he is erasing to fill it into the constructor. The only thing
changing would be that the constructor would take 1 additional
hidden argument and since the argument is filled at compile
time it would not brake any code.</div>
<div dir="auto"><br>
</div>
<div dir="auto">In case 2 we are in some generic context like a
nested class or a generic method. In both cases the actual
type of T will be available. Such situations might require
multiple passes to solve all dependencies. Then we can proceed
like in 1.</div>
<div dir="auto"><br>
</div>
<div dir="auto">In case 3 we are dealing with legacy code and
the type is always object. (Foo foo = new
Foo(java.lang.Object))</div>
<div dir="auto"><br>
</div>
<div dir="auto">In case 4 we are dealing with an open type
bound. The type is not constrained so we can only assume
Object (Foo<?> foo = new Foo<>(java.lang.Object))</div>
<div dir="auto"><br>
</div>
<div dir="auto">In case 5 we have a upper constrained type
bound. We can assume any Object passing that bound Is a
subclass of String (Foo<? extends String> foo = new
Foo<>(java.lang.String))</div>
<div dir="auto"><br>
</div>
<div dir="auto">In case 6 we have a lower constrained type
bound. The Object passing this type bound could be Object.
(Foo<? super String> foo = new
Foo<>(java.lang.Object))</div>
<div dir="auto"><br>
</div>
<div dir="auto"> </div>
<div dir="auto"><br>
</div>
<div dir="auto">We would store the types at constructor or
Method Invocation as arguments and then map them to the
accessor T.class. This would allow type checking of T at
runtime by tracing the real type at compile time.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Since the type of T.class would be
Class<T> or Class<?> we would not need to create a
method or a class for each different version of the method or
class like other languages do.</div>
<div dir="auto"><br>
</div>
<div dir="auto">I’m not quite sure how reflection is implemented
but I’m sure there is a central invocation where the compiler
could add the T.class argument. Of course we would need a way
for reflection to specify the type T for this to work. We
would simply need a method that is designed for generic
classes like “<T> Constructor<T>
getGenericConstructor(Class<?>[] typeParameterTypes,
Class<?>… parameterTypes)” (could have a better
signature).</div>
<div dir="auto"><br>
</div>
<div dir="auto">If the “getConstructor” is used on a generic
class there would be a warning and the parameters would be set
to Object (resulting in a raw object like any Objects
generated by reflection currently are).</div>
<div dir="auto"><br>
</div>
<div dir="auto"> </div>
<div dir="auto"><br>
</div>
<div dir="auto">Risks:</div>
<div dir="auto"><br>
</div>
<div dir="auto">It would require the addition of n fields to any
generic class or method where n stands for the number of
generic arguments, which could result in performance and
memory issues when adding this many new fields to the heap and
stack. This issue could be reduced by only adding this
mechanism when T.class or instanceof T are actually used in
the context and would be skiped if the field is not used in
the first place. Resulting in unchanged field count in all
class files if the feature is used nowhere.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Another rist would be the obvious change in
class files, since the hidden arguments need to be stored at
compile time near the invoke of the method/constructor.</div>
<div dir="auto"><br>
</div>
<div dir="auto"> </div>
<div dir="auto"><br>
</div>
<div dir="auto">This is just an idea based on my knowledge on
generics in java.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Please feel free to correct any misconceptions
in this idea and tell me if I missed something.</div>
<div dir="auto"><br>
</div>
<div dir="auto"> </div>
<div dir="auto"><br>
</div>
<div dir="auto">Great regards</div>
<div dir="auto"><br>
</div>
<div dir="auto">RedIODev</div>
<div dir="auto"><br>
</div>
<div dir="auto"> </div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
</div>
</blockquote>
<br>
</body>
</html>