So where this brings us is back to something that might feel like
the four-bucket approach in the third bullet above, but with two
big differences: atomicity is an explicit property of a class,
rather than a property of reference-ness, and a B3.ref is not
necessarily the same as a B2.
I don't follow how a B3.ref != a B2, unless you just mean that you can
have a reference to a bogus instance more easily than B2 can (which
takes serialization/reflection to do that).
It means that a B3.ref is exactly as subject to tearing as the
same-atomicity B3, whereas a B2 is not.
- B3 classes can further be marked non-atomic; this unlocks
greater flattening in the heap at the cost of tearing under race,
and is suitable for classes without cross-field invariants.
Non-atomicity accrues equally to B3.ref and B3.val; a non-atomic
B3.ref still tears (and therefore might expose its zero under
race, as per friday's discussions.)
Am I right that this "non-atomic" marker would be ignored for classes
like Integer where the vm can tell that it can just give you the best
of both worlds?
We can provide atomicity semantics for sufficiently small objects at no
cost. In practicality this probably means "classes whose layout boils
down to a single 32-bit-or-smaller primitive, or a single reference".
But seriously, we won't get away with pretending there are just 3
buckets if we do this. Let's be honest and call it B4.
"Bucket" is a term that makes sense in language design, but need not
flow into the user model. But yes, there really are three things that
the user needs control over: identity, zero-friendliness, atomicity. If
you want to call that four buckets, I won't argue. The real discussion
here is whether these controls need to be *separate*. And I think they do:
- The premise of Valhalla is that the VM can't guess whether identity
is needed, so the user has to explicitly disavow it to enable more goodies;
- Classes like LocalDate have no good zero, so the user needs to be
able to disavow the zero value when it doesn't fit the semantics of the
class;
- (the controversial one) Atomicity is simply too confusing and
potentially astonishing to piggyback on "primitive-ness" or
"reference-ness" in a codes-like-a-class world.
Would I be right that we can achieve primitive unification even
without B4? There is nothing wrong with our delivering many
performance gains while leaving others on the table for later.
Yes, delivering primitive unification first means you can't have flat
Complex yet.