one class, two types, many bikesheds

John Rose john.r.rose at oracle.com
Wed Jul 13 19:43:18 UTC 2022


The latest iteration of the user model for value classes makes it 
crystal clear that one value class `C` defines two types.

The second type is named `C.val` (at present, until that bikeshed is 
repainted).  This is the “value companion” to `C`, or maybe its 
“companion value type”.

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 
*really*?” and “what’s a type *really*?”

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.

In some of our discussions we have called the other companion type of 
`C`, which is the (nullable) reference type, by the name `C.ref`, as if 
it were something you could write in source code.  Perhaps I should be 
saying `C.__REF` to avoid giving that impression.  But perhaps not.

(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.)

(Note also that the “raw type” of a generic class is named by just 
the class name, sans type arguments:  Plain `List` instead of 
`List<String>`.  And not `List.raw`, at least not today.)

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.

If we do this, it makes some further sense to give them symmetrical 
names, `C.ref` and `C.val`.  We then say that the class name `C`, used 
in a context that requires a type, is “just sugar” for the more 
exact `C.ref` (and certainly not `C.val`, or you would have used that 
name).

Are there other uses for `C.ref`?  I can think of just two:

  - For type variables (*which are not classes*) `T.ref` (or some other 
bikeshed color) means “recover the reference companion, even if the 
generic argument was a value type”.

  - 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!)

The use `T.ref` lends weight to making the companions symmetric.  You 
can go from `C` meaning `C.ref` to `C.val` in `List<C.val>` and then 
inside `List` you can go back to `C.ref`.  It’s a two-way street.

There is a limit to treating the two companions symmetrically.  Do we 
really want to allow inner declarations of the form `public companion 
type C.ref;`, on the grounds that we do so for the companion `C.val`?  
No, because reference types are “hardwired” by present JVM 
specifications, and presumably future ones.

Maybe we will turn, in the end, to a maximally asymmetric design, with 
no symmetrical treatment anywhere; no `C.ref` in particular.  But the 
cost of that is never being able to refer unambiguously to `C` as class 
or as ref-type, except using informal notations or narrative prose.

At the moment, though, I like these rules, personally:

  - For a value class name `C`, `C.val` names a type.
  - For any class or interface name `C`, `C.ref` names a type, meaning 
the same thing as `C`.
  - For any type variable `T` (in new generics), `T.ref` names a type.
  - Maybe:  For any type variable `T` (in specialized generics?), 
`T.val` also names a type.
  - The ref and val suffixes cannot be applied elsewhere.  (So no 
`C.ref.val`.)

Comments?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220713/ff206e4b/attachment.htm>


More information about the valhalla-spec-observers mailing list