Let's take a detour, and try to answer to the question, how do we do reflection 
on method with Q-types ?
Given that reflection is using the class java.lang.Class, it means that we need 
a class that represents a L-type and a class that represent a Q-type.

Correct.  In addition to all sorts of VM reasons for this, users need a way of distinguishing between

    m(Point.ref p)
and
    m(Point p)

with reflection, MH.Lookup, etc.

The class that represents a Q-type does not have to be a 'real' class, the same 
way int.class (Integer.TYPE) is not a real class,
it's a mirror class that represent 'I' in the method signature, same with 
void.class (Void.TYPE) represent 'V'.

Correct.  We've been calling these "secondary mirrors".  Note that with extended primitives, it is possible (though not required) that the secondary mirror reflect almost everything that the primary does -- methods, fields, supertypes, etc.  Alternately, they could be more like int.class, which is pretty limited.

Unfortunately, though, we run into a user expectation problem: users will reasonable expect that if they reflect over

    m(Point p)

they will get Point.class back.  Since the user views "Point" as the primary type (Point.ref is a supporting player), they'll expect Point.class to be the "important" mirror.  This asymmetry with the current state of affairs is a challenge.

So the class that represents a Q-type is a mirror class synthesized by the VM 
at runtime.
Given that it is synthesized, i believe it should be only accessible using a 
method of java.lang.Class,
by example
   Complex.class.mirrorType()  // the name "mirror" is perhaps not the best

Stepping back, what you're saying is to expose only Point.class, and make it harder to get at the "other" mirror, such as by relegating it to a method like Class::otherMirror.  This is a reasonable move, but it does run smack into the above problem -- that if there's one mirror, users will expect Point.class to reflect the Point type they are most familiar with, which is QPoint.

I propose to introduce a new kind of primitive class, the builtin primitive 
class, that

Whether we call it that, or summon it by magic, we are stuck with some form of this anyway, because of the asymmetries you've observed; the existing int/Integer pairs have subtle differences from declared Point/Point.ref pairs.  There will have to be some special pleading for built-in/legacy/basic primitives.

I think where you're going is some flavor of this:

    special-legacy-backwards value class Integer
        with-legacy-primitive int { ... }

where we declare the Integer/int pair, but do so through Integer, but declare it to be backwards from the other primitives, where there are only eight of these allowed.

Reply via email to