<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">On 19 Jul 2022, at 10:54, Kevin Bourrillion wrote:</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">…My own answer to the question has been
<br>
Understanding
<br>
classes and types in Java
<br>
<<a href="https://docs.google.com/document/d/1G5dNQ0kQwA5zefGdP_nvFJByb63QNlz0XiSjltiJM84/edit" style="color: #777777;">https://docs.google.com/document/d/1G5dNQ0kQwA5zefGdP_nvFJByb63QNlz0XiSjltiJM84/edit</a>>
<br>
(comments
<br>
welcome).
<br>
I see a class as a way to "configure" and feed behavior into a type (apart
<br>
from classes *also* serving as bundles of static members). It's a fairly
<br>
subservient relationship, which feels right to me.</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">Yes, I like your document (at about a 90% level). It’s helpful to mention it here.</p>
<p dir="auto">I think it’s a good observation that static members are properties only of classes while non-static members are primarily properties of types.</p>
<p dir="auto">(All members are in classes to start with but in your document non-statics quickly lift to types in practical usage. There are surely times when members stay in their class. Reflection comes to mind.)</p>
<p dir="auto">I also like your observation that the principal type of a class can be obtained by asking for the type of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">this</code>. It’s clean.</p>
<p dir="auto">It might be too clean for us, in fact, because the observation is likely to clash with some very different but also reasonable expectations, which would ask that the principal type of a class be the meaning of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code> (unadorned by <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">.ref</code> or <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">.val</code>), or that the principal type of a class be represented by the mirror which you get when you call <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">Object::getClass</code> on an instance.</p>
<p dir="auto">I think I would like all of the above questions to be answered by <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.ref</code>, even though there are plenty of times when someone will propose or expect that <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.val</code>, or something else, is the answer.</p>
<p dir="auto">(Oh, and please please do not have <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">Object::getClass</code> return different values for variables of type <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.ref</code> and <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.val</code>; I think I see that suggested from time to time!)</p>
<p dir="auto">Your appeal to <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">this</code> has a special benefit when <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code> is generic: It captures the most general type possible, of the form <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C<T></code>.</p>
<p dir="auto">(Except for conditional methods if we ever do those; then <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">this</code> might have a conditional bound on a parameter. The root problem is that <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">T</code> will probably mean something subtly different in a conditional method, so <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C<T></code> doesn’t mean just one type everywhere in <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code>.)</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">(Sorry for digression: you could also say one class engenders many array
<br>
types, though. I think it helps to fully distinguish predefined,
<br>
user-defined, and composed types. Setting aside value classes temporarily:
<br>
each class directly defines just one type, which is the type of `this`
<br>
inside the class itself (the "implicit type", or the "this-type"). That's
<br>
the all-important type whose member signatures are seen in the class and
<br>
whose supertypes are seen in the class signature. Other types can be
<br>
composed out of the defined types: array types, type variables,
<br>
intersection types I guess, and relevant to us here, all *other*
<br>
parameterized types beyond the implicit type. That is, imho it's most
<br>
fruitful to understand those parameterized types as deriving from the
<br>
implicit type/"this-type", with member signatures and supertypes being
<br>
calculated from that implicit type via substitution, rather than to see
<br>
them all as popping directly off of the generic class.)</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">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.</p>
<p dir="auto">It’s an interesting outcome (of your <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">this</code> position) that <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C<T></code>, out of all the generic instances of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code>, is elevated to principal position, and all other <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C<U></code> are mere projections of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code>.</p>
<p dir="auto">(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 <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code>, when <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code> is generic, is its <em>raw type</em>. That is much less useful for speaking about the type of expressions derived from <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">this</code>, but it aligns much more closely with the other “questions” I alluded to above: “What is the type denoted by merely the class name <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code>?” And “What is the mirror returned from <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">Object::getClass</code> when invoked on an instance of class <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C</code>?”)</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">I see some sense in your argument, but I still can't think of a reason I'd
<br>
want to see `ClassName.ref` in source code. It seems like that can't add
<br>
any information.</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">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 <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">public</code> on an interface member where you didn’t need to? Again, I’d call that choice a matter of stylized clarity.</p>
<p dir="auto">Depending on how type inference works, <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">ClassName.ref</code> vs <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">ClassName</code> might affect TI, as <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">List<ClassName.ref></code> vs. <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">List<ClassName></code>. This is, I think, the case with certain drafts of Valhalla-related generics.</p>
<p dir="auto">I made a sly reference to null-inference. As with type inference, I could imagine designs of NI where <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">ClassName.ref</code> vs <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">ClassName</code> produces a different inference about null. Suppose there’s some way of saying, for <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">ju.Optional</code>, that only a dope would make null values of that reference type. Then <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">Optional.ref</code> could possibly be a way of saying, “I’m that dope, bear with me.”</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">…
<br>
- Maybe: For any type variable T (in specialized generics?), T.val
<br>
also names a type.</p>
</blockquote><p dir="auto">If I ever see `T.val` (except maybe the case of `T.val[]`??) I will assume
<br>
some kind of templating must be going on, since we'll all have learned
<br>
early on that there is no polymorphic interaction with values. Is that your
<br>
expectation too?</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">I’m imagining, at least, some sort of additional “leakage” of ref/val distinctions into the scope of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">T</code>. We have such leakage already otherwise <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">T.ref</code> wouldn’t be useful; it happens when a generic API is bound to type arguments and <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">T</code> looks like <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.val</code>. I think the consensus is that the use cases don’t support doing the reverse, of allowing <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">T.val</code> to mean <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.val</code> when <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">T</code> is <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.ref</code>, but it’s logically possible isn’t it? And if so a use case may show up.</p>
<p dir="auto">Independently, something like what Remi discusses, of flattening to val-type inside a generic bound to a ref-type, could be a use of <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">T.val</code>. I think you surmised that: <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">new T.val[n]</code> could be an optimistic dynamic buffer, if the actual type <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.val[]</code> 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 <code style="margin: 0; padding: 0 0.4em; border-radius: 3px; background-color: #F7F7F7;">C.val</code>.</p>
</div></div></body>
</html>