Value types questions & comments
kevinb at google.com
Thu Apr 14 22:18:51 UTC 2016
On Tue, Apr 12, 2016 at 1:51 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
One terminology we’ve been experimenting with is having “class” and
> “species” (think back to middle school: kingdom, phylum, class, order,
> family, genus, species.) List is a class; List<int> and List<erased> are
> species of List. Similarly, the boxed projection and the value projection
> of Complex are both species of class Complex.
> Not clear whether this is the right terminology, but it gives users a way
> to to keep thinking that List is a class, while recognizing that the beasts
> List<int> and List<erased> are at the same time both of class List and also
> of different species.
Just saying: the need to introduce "species" is an example of how this
proposal makes Java fundamentally more complex and confusing, in a way that
will affect everyone.
So, how about:
> - Java has always had values
> - Primitives are the BUILT-IN values
> - Java now gets USER-DEFINED values in addition to USER-DEFINED classes
> - USER-DEFINED values and classes can have fields, methods, constructors,
> and implement interfaces
> Does this stacking make it sound less radical?
I still think this loses compared to simply admitting that there are now
three kinds of types. I can tell that we *want* that to not be true, but we
will not achieve that.
Using a value type for something that *isn't a value* raises alarm bells
> for me. At the minimum I would expect this user to have to implement eq/hc
> by hand, because the default behavior users want 99% of the time is (deep)
> content-based equality.
> This may be the reality-distortion field speaking, but in my view a
> reference *is* a kind of value — albeit a very special kind. They’re
> immutable, like other values. Almost all their state is encapsulated (they
> can be compared by identity, that’s it). They can only be constructed by
> privileged factories (we call these constructors.) But, ultimately, they
> behave like values — they are passed by value, they have no identity of
> their own.
Well, FYI, this confuses and worries me.
For the Cursor class, the natural definition of equals *is* the
> componentwise one — two cursors are the same if they refer into the same
> source at the same position. But yes, there are cases where we’d want to
> hand-override equals (which is allowed) to do a deeper comparison
> (generally when our components are value-like references, like strings or
> dates or big decimals.)
And again, I think this orientation is very wrong. Deep content-based
equality is what most users will expect, and will want most of the time. If
we don't do that, I think we may be fairly accused of thinking too much
about the kind of code *people like us* write, not the kind of code that
most Java users write.
This actually gets back to a much broader point. This whole project is
motivated by performance. However, it would be very sad if it does not
solve a second problem at the same time, because it can. Even Java
developers who are content with the performance foibles of their existing
"value-based classes" are constantly irritated by the burden and bug-prone
nature of writing/maintaining such classes. At Google we have resigned
to *code-generating* these things, which we are currently doing 16,500
times and climbing. Few of this resemble your stated use cases (cursors,
tuples, numerics, etc.). They are just the everyday data that our
applications pass around. imho, it really should be an explicit goal of
this project to make hacks like that obsolete. A lot of people would cheer
that feature even if these still compiled to regular old classes!
Another place where references to mutable objects will show up in values is
> if we use values as a substrate for multiple return / tuples. Here, the
> value is just an ad-hoc container for multiple values — and object
> references are entirely reasonable to use in this context.
> Gratuitous aside about language syntax even though it is not actually
> important right now: since we write "enum Foo" not "enum class Foo", I
> would be quite surprised if we used "value class" here, since between the
> two only enums are the ones that are real classes in every sense of the
> Sure, this is one of our tools for helping frame the correct mental
> model. If we decide that the terminology falls out as “classes are the
> entities that have fields, methods, and constructors”, then “value class”
> reinforces that. But we could go other ways too.
Just saying, it would be odd to use a rationale for "value class" that
equally well argues for "enum class". This is a tangent though.
Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at google.com
More information about the valhalla-spec-observers