minimal value types proposal
Dan Smith
daniel.smith at oracle.com
Mon Aug 29 23:17:13 UTC 2016
Some high-level feedback from me:
I think the idea is reasonable. In other circles, we might call this a "milestone". Should we define a first milestone that we're willing to commit to strongly, with some sort of distribution channel (something better than build-your-own-JDK) and some level of support commitment to users who want to get their hands dirty? Sure, absolutely.
There are some design decisions that surprise/confuse me. Basically, this is me saying "YAGNI" over and over again:
1) Automatic boxing adds tons of complexity, and I don't see the benefit. The feature eliminates boilerplate and supports migration, but I'm not looking for either of those in a minimal first step. We're talking about a handful of value types, which can easily be defined like this:
class Val {
public final int i;
public final int j;
public static ValBox box(Val x) { return new ValBox(x); }
public static Val unbox(ValBox b) { return b.x; }
}
class ValBox implements Foo {
public final Val x;
public ValBox(Val x) { this.x = x; }
}
Get rid of boxes, and you can get rid of interfaces, default methods, automatic conversions, constructors, ...
2) Instance methods also add tons of complexity. Again, they only exist for convenience and migration. If static methods can operate on value types, that's all you need. No longer necessary to deal with bytecode written to operate on an L-typed 'this' and somehow re-interpret it for a Q-typed 'this'. No longer necessary to deal with Object methods (because no operation supports invoking them).
(If we really do want instance methods, I suggest making 'this' Q-typed to begin with, not diverting resources into figuring out how to make L-typed instance methods efficient.)
3) The minimal feature set for basic operations -- field getters, default value, withers, comparison, arrays -- is a class (e.g., ValueTypeSupport) with bootstrap methods that can be called via invokedynamic. No need to touch MethodHandles.Lookup, etc.
More generally, why so much attention given to reflection? Sure, you need class objects to represent all the JVM's types. But member lookup? Fields, Methods, Constructors? These do not seem necessary.
If I squint, I can kind of see how the idea is that somebody might want to write reflective code to operate on values, since they don't have language support. But almost everything has to be boxed when using these libraries, which means if you care about performance (which is why you're using this prototype), you're going to be spinning bytecode to do your low-level operations. If this is the use case, I think a better use of resources would be to surface Q types in the language.
4) I don't love hacking CONSTANT_Class to encode new types, but I can probably live with it. My preference is to design it the "right" way -- however we envision these ultimately being expressed -- rather than this intermediate step in which everybody learns to interpret some new syntax, only to turn around and deprecate that syntax a little while later. (I realize it's probably easier to change string formats than it is to add a new constant pool form.)
I don't think it's necessary to support Q types as the receivers of CONSTANT_Fieldrefs and CONSTANT_Methodrefs. The receiver can be a vanilla CONSTANT_Class, and the client (in this case, the 'vgetfield' API point) can figure out what to do with the resolved reference.
—Dan
More information about the valhalla-spec-observers
mailing list