<div dir="ltr"><div>Sorry for delay</div><div><br></div><div><br></div><div dir="ltr">On Wed, Jul 13, 2022 at 12:43 PM John Rose <<a href="mailto:john.r.rose@oracle.com">john.r.rose@oracle.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div><div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">The latest iteration of the user model for value classes makes it crystal clear that one value class <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code> defines two types.</p>
<p dir="auto">The second type is named <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.val</code> (at present, until that bikeshed is repainted). This is the “value companion” to <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code>, or maybe its “companion value type”.</p>
<p dir="auto">The term “companion” tries to capture the idea that the class doesn’t come alone but travels with some friends, its types. But this pulls in a long and difficult discussion about the exact relation between a class and a type. And then (inevitably) “what’s a class <em>really</em>?” and “what’s a type <em>really</em>?”</p>
<p dir="auto">I think we want to make a distinction between a class and a type. A class is primarily a bunch of source code, later compiled into a classfile. A type is the primary static attribute of a variable in source code, determining its range of values and set of valid operations. As later compiled, the type determines a JVM-level type (usually what we call a field descriptor). The type probably also determines something of the eventual format of the variable in a real machine, although that’s a secret the JVM keeps.</p></div></div></div></blockquote><div><br></div><div>(I know the 3 people regularly participating in these threads are already well-aware, sorry...) My own answer to the question has been <a href="https://docs.google.com/document/d/1G5dNQ0kQwA5zefGdP_nvFJByb63QNlz0XiSjltiJM84/edit">Understanding classes and types in Java</a> (comments welcome).</div><div>I see a class as a way to "configure" and feed behavior into a type (apart from classes <i>also</i> serving as bundles of static members). It's a fairly subservient relationship, which feels right to me.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">In some of our discussions we have called the other companion type of <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code>, which is the (nullable) reference type, by the name <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code>, as if it were something you could write in source code. Perhaps I should be saying <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.__REF</code> to avoid giving that impression. But perhaps not.</p>
<p dir="auto">(A generic class can engender many, many types. Is this a whole mob of companion types? Perhaps not, but it does call for a clear term for this other relation of classes to types.)</p></div></div></div></blockquote><div><br></div><div>(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.)</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">(Note also that the “raw type” of a generic class is named by just the class name, sans type arguments: Plain <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">List</code> instead of <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">List<String></code>. And not <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">List.raw</code>, at least not today.)</p>
<p dir="auto">To me it seems useful to treat the two types with a certain amount of symmetry. There is one class, and two companion types, not a class (which is also a type), plus its companion (value) type.</p>
<p dir="auto">If we do this, it makes some further sense to give them symmetrical names, <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code> and <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.val</code>. We then say that the class name <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code>, used in a context that requires a type, is “just sugar” for the more exact <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code> (and certainly not <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.val</code>, or you would have used that name).</p></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">Are there other uses for <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code>? I can think of just two:</p>
<ul>
<li>
<p dir="auto">For type variables (<em>which are not classes</em>) <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">T.ref</code> (or some other bikeshed color) means “recover the reference companion, even if the generic argument was a value type”.</p>
</li>
<li>
<p dir="auto">For extreme stylized clarity in source code, where someone wants to emphasize that a variable is nullable. (Could this interact with null-inference schemes? Oh, certainly!)</p></li></ul></div></div></div></blockquote><div><br></div><div>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.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="font-family:sans-serif"><div style="white-space:normal"><ul><li>The use <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">T.ref</code> lends weight to making the companions symmetric. You can go from <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code> meaning <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code> to <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.val</code> in <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">List<C.val></code> and then inside <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">List</code> you can go back to <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code>. It’s a two-way street.<br></li></ul>
<p dir="auto">There is a limit to treating the two companions symmetrically. Do we really want to allow inner declarations of the form <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">public companion type C.ref;</code>, on the grounds that we do so for the companion <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.val</code>? No, because reference types are “hardwired” by present JVM specifications, and presumably future ones.</p>
<p dir="auto">Maybe we will turn, in the end, to a maximally asymmetric design, with no symmetrical treatment anywhere; no <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code> in particular. But the cost of that is never being able to refer unambiguously to <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code> as class or as ref-type, except using informal notations or narrative prose.</p>
<p dir="auto">At the moment, though, I like these rules, personally:</p>
<ul>
<li>For a value class name <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code>, <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.val</code> names a type.</li>
<li>For any class or interface name <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code>, <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref</code> names a type, meaning the same thing as <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C</code>.</li>
<li>For any type variable <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">T</code> (in new generics), <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">T.ref</code> names a type.</li>
<li>Maybe: For any type variable <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">T</code> (in specialized generics?), <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">T.val</code> also names a type.<br></li></ul></div></div></blockquote><div><br></div><div>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?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div style="font-family:sans-serif"><div style="white-space:normal"><ul>
<li>The ref and val suffixes cannot be applied elsewhere. (So no <code style="margin:0px;padding:0px 0.4em;border-radius:3px;background-color:rgb(247,247,247)">C.ref.val</code>.)</li>
</ul>
<p dir="auto">Comments?</p>
</div></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif"><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px">Kevin Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px"> Java Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px"> Google, Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px"> <a href="mailto:kevinb@google.com" target="_blank">kevinb@google.com</a></span></div></div></div></div></div></div></div></div>