Value types questions & comments

Kevin Bourrillion kevinb at google.com
Mon Apr 11 20:53:03 UTC 2016


Hi all,

Okay, this is a bit overdue, but I'm finally digging into "state of the
values" again. Not even going to dig into the specialization stuff yet in
this email.

My perspective on this: Since Java has had only two "kinds of types" for
20+ years -- and since the tension between those two is already a major
source of confusion and bugs for intermediate programmers -- adding a third
kind now is a *Very Big Deal*. It needs to be as simple as possible to
understand this new kind, as nothing but a "natural" hybrid of the other
two. The fewer asterisks we need to put on that simple model, the better.

I've gathered that it's like a reference type in that it's a named,
user-defined type that can have fields (of any kind), methods and
constructors (getting eq/hc/ts for free, kind of like enum classes get
valueOf for free, I assume), and can implement interfaces.

But I think it resembles a primitive in pretty much every other way?

   - No identity (so mutability isn't even a question)
   - Can't be null
   - Can't have subtype or supertype (excepion: as above, value types can
   implement interfaces)
   - Does not extend Object, so synchronization/wait/notify not possible
   - Not heap-allocated (locals on the stack, fields and array values
   inlined)
   - Can be boxed to an Object ... although *boxing works differently

So first off: have I got all that right?

Next I just have a laundry list of random questions.

Conceptual question: is a user-defined value type a "class"? A "yes" and a
"no" answer both seem defensible, and of course we have to choose one and
defend it. And notably, whichever way we decide it, users are going to have
to rethink their preconceived notions of what a "class" is no matter what.
(This gets back to my statement that what we're doing here is a Very Big
Deal. These are bedrock concepts we're tampering with.)

On the one hand, classes are things that have fields and methods, so yes, a
value type is a class. On the other hand, one expects classes to have
"instances"/"objects", pointed to by references, which these don't. Also,
you expect to be able to call getClass() and get something useful back
(that knows what methods are present, what interfaces are implemented) and
that doesn't seem possible in the general case here (but could maybe(?) be
faked in cases where the static type of the value is known to the compiler).

It's nice that a value type can implement interfaces. But I get confused
when I try to think through the implications of this. I get that when
referring to it as the interface type, boxing *may* occur. I'd expect
eq/hc/ts on the box to pass through to the value itself (two different
boxes of equal values are equal). But... maybe most of my confusion is just
stemming from getClass() again. What would it return? Could the returned
Class possibly have all the metadata a user might expect? I think not?

Re: "Large groups of component values should usually be modeled as plain
classes", I'd VERY much like avoid putting that responsibility onto the
user if at all possible. Is there a reason why the VM can't simply decide
"this is past my threshold, so I'm gonna box it instead of putting it all
on the stack" and not make the developer worry about it?

Re: "Cloning a value type does not strictly make sense," well, *technically*
when a value includes fields of Cloneable reference types, you might want a
deep-clone of that. However I lean toward thinking this is too weird to
bother supporting. Users should really be dissuaded from including
references to *mutable* types in their value definition in the first place.

Which actually raises another issue. If my value type has no way to include
an int[] *unmodifiably*, that would be extremely sad, right?

Going to stop there for now!


-- 
Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at google.com


More information about the valhalla-spec-observers mailing list