Finding the spirit of L-World

forax at forax at
Tue Jan 8 16:20:06 UTC 2019

----- Mail original -----
> De: "Brian Goetz" <brian.goetz at>
> À: "Remi Forax" <forax at>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at>
> Envoyé: Mardi 8 Janvier 2019 14:03:18
> Objet: Re: Finding the spirit of L-World

>> Introducing a ValObject as super or having the ACC_VALUE bit are two
>> representation of the same thing for the VM.
>> In both case, we need to load the class to know if it's a value type or not, and
>> in Java, the class loading is delayed which works well for reference type but
>> not well for value type, if you have class that has a field which is a value
>> type, you need to know if the field is a value type or not to be able to
>> flatten it. With your proposal, the VM doesn't know if a field contains a value
>> type or not until it's too late. Or are you suggesting to have a shape shifting
>> objects (Skrulls objects) ?
> No.  As you say, from the VM perspective, the two are equivalent, as
> long as RefObject and ValObject are loaded super-early (which of course
> they can be.)   To know whether to flatten a field is an orthogonal
> question.  We explored an ACC_FLATTENABLE bit, and in BUR we settled on
> "flatten Qs, don't flatten Ls" -- but we could change again.  But that
> is completely separate from how the class is declared.

we've changed because you need to know if a value type is flattenable at 3 places, field, array creation and method parameters, ACC_FLATENABLE only works for field, you don't need any flag for the array creation because at that time the class of the array component need to be loaded, we had no real solution for the method signature.

anyway, what you are thinking is more in term of the language than the VM, so yes, you can have a ValObject.

>> same issue here, you want to know if something is nullable or not when you
>> verify the bytecode, but at that point the class may not be loaded so you don't
>> know if the class implements Nullable or not.
> Again, you're talking at a different layer.  At the VM level, we still
> use L/Q to describe nullability of _instances_.  Putting Nullable in the
> type system let's the _language_ apply it to _types_, as in a type bound:
> <T extends Nullable>.  Different things.

BTW, i believe it should be <T extends Object & Nullable> otherwise, the interface Nullable will appear in the code when erased.

>> Currently, you can not do == on value types, i.e. point1 == point2 doesn't
>> compile, if you want a unified equality, you have to use equals.
> Right.  And I'm saying, we can't sell that.  Values should work like an
> int; you can compare ints with ==.   I think the "Currently" story
> doesn't wash.

You can not use the "work like an int" argument here, a value type can contain references, so it doesn't work like an int.
And what you propose as semantics for == is not the == semantics of a primitive type,
  1/ it's an extension of that semantics.
  2/ your proposed extension make it awful (see just below).

value class IntList {
  private final int value;
  private final Object next;
  IntList(int value, Object next) { this.value = value; = next; }

var list = IntStream.range(0, 100_000).box().reduce(null, (next, value) -> new IntList(value, next)).orElseThrow();
list == list // will gently loop over the list of 100_000 links and stack overflow !

John proposed to stop the recursivity at some point, but it will be very surprising too !

I've though about doing a component wise comparison if there is no reference in the value type, but it means that the semantics will vary depending on the implementation (will behave differently by example if the value type encapsulates a reference or an int as index).

So for now, i think the only possible semantics is to consider that '==' means an address comparison for all kind of classes (reference or value class), so a value class acts like a class for == and given that a value has no address, it should return false.


More information about the valhalla-spec-experts mailing list