On Thu, Jul 21, 2022 at 4:01 PM John Rose <[email protected]> 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. | [email protected]
