[External] Foo / Foo.ref is a backward default; should be Foo.val / Foo

Dan Heidinga heidinga at redhat.com
Mon Apr 25 18:47:37 UTC 2022


On Mon, Apr 25, 2022 at 1:59 PM Kevin Bourrillion <kevinb at google.com> wrote:
>
> On Mon, Apr 25, 2022 at 1:19 PM Brian Goetz <brian.goetz at oracle.com> wrote:
>>
>> Changing from a B2 -> B3 changes the default spelling from "L" -> "Q".
>> Why does this have to be done atomically?
>
> (First note that I'm thinking in terms of source compatibility, if that makes a difference.) I mostly just mean that anyone anywhere might be counting on the type being nullable. Is it possible to fix all that code ahead of time to be nullness-agnostic, i.e. the very same code works whether the type is nullable or not? I feel like it would be hard to get *everything* that way.

You're right it's more source compatible assuming that existing
descriptors are never updated to use ".val". Old code would keep
working while newly added methods could use ".val" to benefit.  Once a
container is updated to use .val for backing storage then we're
dealing with null pollution from those old methods and someone has to
do something to adapt.  And if storage locations aren't updated, then
why migrate the type?  I'm not sure this is better?

We've eased the identity -> B2 migration path (and ended up in a good
spot doing it!) but this may be over-rotating on the migration axis.
The main use case I'm aware of for a B2->B3 migration is better memory
density in the heap.  Converting from our L->Q via checkcast will
throw on null (plan of record, correct?).  Once we migrate the backing
storage to be a B3, we need some answer for the missing null case or
we're just leaving a footgun for the users at runtime.

>From Brian's email:
> The API point has to stay LOptional, but the field could migrate further to QOptional, and there’s definitely value in that.

To migrate, either the field has to grow a ".val" or the descriptor
has to grow a ".ref".  Someone has to make an explicit choice.

As I said above, migration is one use case.  The author of B3 api is
not going to be happy needing to put ".val" all over their code and
neither will their users.
primitive value class Complex {
  long re;
  long im;

  static Complex.val add(Complex.val a, Complex.val b) { .... }
  static Complex.val mul(Complex.val a, Complex.val b) { .... }
  static Complex.val sub(Complex.val a, Complex.val b) { .... }
}

Do we want to make this worse to read for the migration use case?

--Dan



More information about the valhalla-spec-experts mailing list