one class, two types, many bikesheds
Kevin Bourrillion
kevinb at google.com
Fri Jul 22 15:07:39 UTC 2022
On Thu, Jul 21, 2022 at 4:01 PM John Rose <john.r.rose at oracle.com> wrote:
> (Oh, and please please do not have Object::getClass return different
> values for variables of type C.ref and C.val; I think I see that
> suggested from time to time!)
>
(plug: imo there are only 3 Object methods that have any business even
*compiling* when called on val receivers.)
Your appeal to this has a special benefit when C is generic: It captures
> the most general type possible, of the form C<T>.
>
> (Except for conditional methods if we ever do those; then this might have
> a conditional bound on a parameter. The root problem is that T will
> probably mean something subtly different in a conditional method, so C<T>
> doesn’t mean just one type everywhere in C.)
>
Agreed. I'd guess it would resemble that method introducing its own type
parameters, bounded by the class's, and hiding them.
(Sorry for digression: you could also say one class engenders many array
> types, though. I think it helps to fully distinguish predefined,
> user-defined, and composed types. Setting aside value classes temporarily:
> each class directly defines just one type, which is the type of `this`
> inside the class itself (the "implicit type", or the "this-type"). That's
> the all-important type whose member signatures are seen in the class and
> whose supertypes are seen in the class signature. Other types can be
> composed out of the defined types: array types, type variables,
> intersection types I guess, and relevant to us here, all *other*
> parameterized types beyond the implicit type. That is, imho it's most
> fruitful to understand those parameterized types as deriving from the
> implicit type/"this-type", with member signatures and supertypes being
> calculated from that implicit type via substitution, rather than to see
> them all as popping directly off of the generic class.)
>
> Yup, when is a related type a true companion, and when is it just a
> projection? We get to define this, and then we have to live with it.
>
> It’s an interesting outcome (of your this position) that C<T>, out of all
> the generic instances of C, is elevated to principal position, and all
> other C<U> are mere projections of C.
>
Yes, in my mind, it is already elevated: it's the type whose supertypes and
method signatures are actually being specified directly by the class.
That's such an essential role it is playing.
> (Surely you already considered and rejected the following alternative
> choice of narrative in your document, which I will state here FTR: The
> principal type of C, when C is generic, is its *raw type*. That is much
> less useful for speaking about the type of expressions derived from this,
> but it aligns much more closely with the other “questions” I alluded to
> above: “What is the type denoted by merely the class name C?” And “What
> is the mirror returned from Object::getClass when invoked on an instance
> of class C?”)
>
Gross! :-)
I think pretending raw types don't exist (as much as possible) leads to
more virtue than vice.
> I see some sense in your argument, but I still can't think of a reason I'd
> want to see `ClassName.ref` in source code. It seems like that can't add
> any information.
>
> I mean it can adds a certain connotation (“stylized clarity” as I said) to
> the code. Have you ever written a fully-qualified name where it wasn’t
> necessary? (I have, when I wanted to emphasize where the symbol came from:
> Such emphasis is connotation not denotation.) Have you ever written public
> on an interface member where you didn’t need to? Again, I’d call that
> choice a matter of stylized clarity.
>
If I do those things, someone else comes along and cleans them up. :-)
> Depending on how type inference works, ClassName.ref vs ClassName might
> affect TI, as List<ClassName.ref> vs. List<ClassName>. This is, I think,
> the case with certain drafts of Valhalla-related generics.
>
> I made a sly reference to null-inference. As with type inference, I could
> imagine designs of NI where ClassName.ref vs ClassName produces a
> different inference about null. Suppose there’s some way of saying, for
> ju.Optional, that only a dope would make null values of that reference
> type. Then Optional.ref could possibly be a way of saying, “I’m that
> dope, bear with me.”
>
fwiw (which isn't much), this all makes me feel uneasy.
> - Maybe: For any type variable T (in specialized generics?), T.val
> also names a type.
>
> If I ever see `T.val` (except maybe the case of `T.val[]`??) I will assume
> some kind of templating must be going on, since we'll all have learned
> early on that there is no polymorphic interaction with values. Is that
> your
> expectation too?
>
> I’m imagining, at least, some sort of additional “leakage” of ref/val
> distinctions into the scope of T. We have such leakage already otherwise
> T.ref wouldn’t be useful; it happens when a generic API is bound to type
> arguments and T looks like C.val. I think the consensus is that the use
> cases don’t support doing the reverse, of allowing T.val to mean C.val
> when T is C.ref, but it’s logically possible isn’t it? And if so a use
> case may show up.
>
Again it just puzzles me, since I expect that part of the whole deal with
value types vs. reference types is that you always need to know exactly
what type you're working with. So how could I interact generically with
`T.val`? Unless templating. The array case seems sensible to me though,
because I can figure that the array's header must be keeping track of the
precise value type.
Independently, something like what Remi discusses, of flattening to
> val-type inside a generic bound to a ref-type, could be a use of T.val. I
> think you surmised that: new T.val[n] could be an optimistic dynamic
> buffer, if the actual type C.val[] were somehow available at that point.
> That would require even more “leakage” of information about type arguments
> beyond the API of a generic and into its method bodies and maybe even field
> types. Eventually you would use such information to “fill in templates”,
> including flattening fields to C.val.
>
--
Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at google.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220722/81cd187e/attachment-0001.htm>
More information about the valhalla-spec-observers
mailing list