User model: terminology

Stephen Colebourne scolebourne at joda.org
Thu May 5 09:48:34 UTC 2022


On Wed, 4 May 2022 at 16:06, Brian Goetz <brian.goetz at oracle.com> wrote:
Overall, things are looking positive in Valhalla.

I agree 100% with Kevin's document, particularly the initial
definitions of Values, Variables, Containers, Kinds of Values and the
essential characteristics of Objects.

I still believe there is a profitable direction of thought in
imagining what Java would be like if references were visible in source
code:

class Person {
  private ref<String> name;
  private ref<LocalDate> birthDate;
  private int customerScore;
}

This way of thinking makes it more obvious why == does what it does
for example. I still think it would be worth exposing an actual
`ref<T>` type as part of Valhalla as it helps join the whole model in
people's minds, and allows null to be managed better (maybe it is just
a new name for `Optiona<T>`?.


I'm onboard with the idea that authors can opt-in to accepting
non-atomicity, although I worry that it will be overused and not
properly understood. I'm also onboard with the idea that authors can
opt-in to accepting that zero-is-ok. I think that both are significant
problems, thus I want both the syntax and defaults to reflect the safe
choice (B2 safe-atomicity zero-not-ok).

>      class B1 { }                 // ref only
>      value class B3 { }           // ref and val projections
>      value-based class B2 { }     // ref only

Given the above, while this reads very nicely, it runs far too big a
risk of exposing bad zeroes.


>   - A term for all non-identity classes.  (Previously, all classes had identity.)

After reading Kevins document I'm a bit wary of using "value" for this
term. Because as per the document, values have a quite specific
meaning in the value-variable-reference model, and I think "value
class" might well be muddying the water. "inline" is OK, but a bit
meh. "primitive" isn't right at all.

I'd like to propose "struct" :

  public class B1 {...}
  public struct B2 {...}

I know that "struct" has some baggage and is usually used for a
compound set of fields, but I don't see any particular reason why it
couldn't fit here. As a word it evokes ideas of a "bundle of memory"
and "being passed around without overhead". It goes nicely in text and
code.

I actually think it is better to *not* use "class" here. Java already
has a thing where one declaration produces multiple classes - enums,
and we generally call them "enum", not "enum class". This is another
reason not to use "value class".

> - A term for  what we've been calling atomicity: that instances cannot
> appear to be torn, even when published under race.  (Previously, all
> classes had this property.)

I'd like to propose "raw" for this term (non-atomicity). I've used it
in my mental model for a few days and it seems to work quite well. IMO
"fragile" or "unsafe" don't quite fit with what I'd expect from a
programming language term. "non-atomic" would be OK, but is a bit
verbose.

  public raw struct B2a {...}

Some phrases:
 "All existing primitives are raw"
 "The JVM may choose to treat a struct as raw even if not defined as
such, but only where it can prove it is safe to do so."

I don't think there is any need to mention raw at the use-site, but if
there was it works well - `Complex.raw c = ...`

>   - A term for those non-identity classes which do not _require_ a
> reference.  These must have a valid zero, and give rise to two types,
> what we've been calling the "ref" and "val" projections.

To me, the term "primitive" is most closely associated with the fact
that zero-is-ok and that there are two projections (int and Integer).
Thus I think the term here is "primitive".

  public primitive struct B3 {...}
  public raw primitive struct B3a {...}

Although there is a case for dropping "struct" in code, the *term* is
clearer with struct. Saying "primitive struct" clearly delineates them
from the original primitives.

For naming, I would say that ".ref" type would get the good name,
leading to ".primitive" as the projection (or perhaps ".val"). A type
aliasing feature could then be used:

  alias int = Integer.primitive
or
  public primitive int struct Integer {...}

I prefer aliasing as it is needed to make sense of the int/Integer
char/Character mess we already have.

HTH
Stephen


More information about the valhalla-spec-comments mailing list