value type hygiene

Remi Forax forax at
Mon May 14 23:13:59 UTC 2018

I think i prefer a declaration site annotation like @ValueBasedClass to a use site annotation ValueRef<V>. 

For me a value based class, if you want to be as compatible as possible, is a reference type (so 'L') that behave like a value type at runtime, so the JIT can see it has a value type at runtime and can unbox it at will and buffer/box it before calling a method at the horizon of the inlining blob. 

So as a library designer, i can choose to either replace a class by a real value type and it will fail if null is present or as a value based class if i value (sorry !) the backward compatibility more than the performance. 

Note that even if we solve the null issue when a reference type is changed to a value type and i think it's not something we should focus on, there is still the problem of the identity, so transforming a reference to a value type will never be 100% compatible. 


> De: "John Rose" <john.r.rose at>
> À: "Brian Goetz" <brian.goetz at>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at>
> Envoyé: Lundi 14 Mai 2018 18:06:05
> Objet: Re: value type hygiene

> On May 12, 2018, at 7:34 AM, Brian Goetz < [ mailto:brian.goetz at |
> brian.goetz at ] > wrote:

>> I get that. What I’m saying is: boxes have a place in the user model. We may
>> hate them, but without them, we likely find ourselves “boxed” into a corner. So
>> I don’t want them to be a library convention; I want them to be understood by,
>> say, asType(). Otherwise we’re playing whack-a-mole.

> I don't fully understand the point you make by "a library convention". Maybe
> "only a
> library convention unknown to the rest of the stack"? The existing box types are
> a library convention. It's even an irregular one (int vs. Integer). The JLS
> recognizes
> them (in the box/unbox rules). Following the JLS, so do asType, core reflection,
> etc.

> Since value types "code like a class" there are new moves for making library
> conventions unavailable to primitive types, and adding an interface super seems
> to be a better move, for value types, than the companion type pattern we must
> use for int/Integer.

> Further, we can meet many of the requirements met by the companion class pattern
> by using the generic-super pattern (V <: ValueRef<V>) in the case of value
> types.

> One requirement *not* met by using the generic-super pattern is run-time
> reification
> of the box types, since before erasure ValueRef<Complex> and ValueRef<Point>
> are different types, but to the VM they are the same type. But I don't think
> that's a
> deal-killer. Maybe you see a problem with the erasure that I don't?

> Specifically: Do we really need a VT version of the reified wrapper type
> Integer?
> That's what I'm trying to question here, at the risk of playing whack-a-mole.
> There
> is serious money to be saved if we can decide the companion class isn't needed
> in the case of value types, even if it is necessary scaffolding for non-L-types.

> It seems to me that most or all of the machinery in reflection and method
> handles
> and the JLS for special-casing the companion classes exists to hoist primitives
> into the L-descriptor world. When the hoisting occurs to a wrapper class, many
> use cases go straight up to Object itself (or to another super of a wrapper).
> Others stay on the wrapper just to make a method call like toString or hashCode.
> Since value types are already classes with methods, and already are
> L-descriptors,
> it follows that they don't need wrapper types very often.

> Expressing nullity is one of those residual use cases; we know it happens
> sometimes
> but the JVM needs help calling it out as a special case. I claim we don't need a
> fully
> differentiated, runtime-reified wrapper type like Integer to handle those
> occasional
> special cases. In the JVM we just need a way to process the nullable VT instance
> as
> an Object or an interface. In the language an erasable static type like
> ValueRef<V>
> works as well as a fully reified companion type like Integer.

> How far should language go in healing the gap between the int/Integer pattern
> and
> the VT/VR<VT> pattern? Probably not too far until we are ready to fully unify
> the
> primitives with values. But there are simple things we could do that might help,
> like making a new notation like C.BOX that connects the various types in new
> ways.

> — John

More information about the valhalla-spec-observers mailing list