Comments on JDK-8198408 please ? (original) (raw)

John Rose john.r.rose at oracle.com
Mon Feb 26 21:46:24 UTC 2018


On Feb 26, 2018, at 9:04 AM, Srikanth <srikanth.adayapalam at oracle.com> wrote:

Frederic and I have been discussing the code sequence that javac should produce for certain more involved attempts to update value fields using withfield. Basically for the test case in JDK-8198408, what should be the bytecode generated for d.c.b.a.x = 11; where x is an int field and a, b, c and d are value classes. I imagine this would call for a.x to be updated via withfield to obtain a', b.a to be updated with a' using withfield to obtain b', c.b to be updated with b' using withfield to obtain c' and d.c to be updated with c' using withfield to obtain d' and for d' to be finally stored back into d - Is that correct ??

This is taking us away from the close coupling between value-based classes and value types. I'm pretty sure it's a bad road with no good destinations.

Notice that none of these expressions has a meaning which can be predicted by referring to value-based object classes:

a.x = 11; a.p.x = 11; … a.p.q.r.s.x = 11;

Not even the first has a meaning predicted from standard Java, since x is a final field in a value-based class. (The other p/q/r/… fields are final, but the whole process stops immediately with x.)

Years ago, at the inception of the value types project, we considered a number of alternative ways to give a meaning to all of these expressions. They are all overly complex for the limited amount of expressiveness we think they will purchase.

The basic problem is that we have to bend the meaning of a.x = 11 with a value type, to include a change to the value of a. No other Java construct does this. This is why it's a puzzle to wedge value field assignment into the language.

Other languages have constructs like this. Nested (flat) C structs behave like this—and almost nobody uses this language feature. Some languages have elaborate property-definition mechanisms which can endow such reference chains with assignable behavior (JS, Perl, VB, looking at you). But we don't want to go there; at the very least we don't want to get on a slippery slope that slides us into programmable properties.

This calls for non-trivial changes to be made to javac - I don't think it is a blocker issue, a solution can be found quickly, but it is a radical departure from how code generation in Javac works today.

More fundamentally, even the single level assignment a.x = 11 is a radical departure. So it's no surprise that javac is unready for such things.

(at the time of withfield emission for updating a.x with 11, the expression stack has been mostly drained and has no trace of the complex sequence of operations that led up to that point. When a' is computed by updating a.x with 11 using withfield, we reach a dead end - there is nothing in the expression stack to write back to. When the updated field is an instance of field of a value instance that is a local variable, the problem is lot simpler - all it calls for an astore which does not expect much from the expression stack as far as the destination is concerned, the astore opcode fully specifies the destination)

Even if we support single-level field assignment (as twisted sugar for withfield) we should not support multiple-level field assignment.

In fact, I'm doubting (again, after several years) the wisdom of allowing even the single-level x.a = 11. It seems to lead the user model into a swamp. And also contains a paradox, that a subexpression on the LHS of an assignment gets modified, in addition to the whole LHS.

Dan Smith once very tentatively suggested defining a new compound assignment operation to capture the subexpression changing behavior, something vaguely like x += __Edit(a = 11). There are lots of variations on such syntaxes; they are easy to come up with. And of course the compound assignment always goes with a plain non-assignment operator, which would be a very direct representation for withfield, something like y=__Edit(x, a = 11) or y=__Edit(x.a, 11).

I think we want some sort of "reconstructor" mechanism like _Edit for scoped-in-place modification of value types. It will take a while to work out the details of such a thing.

Meanwhile, to provide withfield encodings, the single-level a.x=11 is acceptable, given the understanding that it will probably go away when we figure out a story that allows a more natural notation.

(By natural I mean not natural to existing Java but natural to the semantic structure of value types. Something like WITH in VB or Modula-3, or something like Java constructor bodies, sprinkled into other code as sub-blocks.)

We could also represent withfield directly with a temporary extra operator: __WithField(a.x, 11). I think I'd prefer that, because it's more obviously a temporary expedient to be replaced later. Would that be difficult to prototype in javac?

Could the experts weigh in on the required sequence please - before we go down too far deep in implementing anyone presumed sequence ?

Thanks for asking. See above; I think this represents significant parts of Brian's thinking as well as my own.

— John



More information about the valhalla-dev mailing list