Comments on JDK-8198408 please ?

Remi Forax forax at univ-mlv.fr
Wed Feb 28 11:54:58 UTC 2018


Hi Ali,

----- Mail original -----
> De: "Ali Ebrahimi" <ali.ebrahimi1781 at gmail.com>
> À: "John Rose" <john.r.rose at oracle.com>
> Cc: "valhalla-dev" <valhalla-dev at openjdk.java.net>
> Envoyé: Mercredi 28 Février 2018 08:30:12
> Objet: Re: Comments on JDK-8198408 please ?

> Hi,
> Since as far as I know java value types would be immutable, so assignment
> to value class's fields doesn't make sense and should be dis-allowed.
> I have a suggestion similar to Stephan's.
> Some thing as following:
> 
> a = a.with {x:11, y: ...};
> 
> I suggest we have withfields instead of withfield.  This way whole
> expression " a.with {x:11, y: ...}; " can be translated into one jvm
> instruction in bytecode.
> This new jvm opcode can get one value instance and return new value
> instance with one or multiple fields updated regard to original value
> instance.

I've asked the very same question at last valhalla experts meeting,
see http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2018-February/000581.html

The short answer is that this new bytecode will be alien among the other bytecodes, a pain to implement in the interpreter and is better implemented with an invokedynamic compounding a default + n withfields. 

> 
> And syntax for value instance creation.
> ValType v = ValType {x:11, y: ...}    // JavaFX Object literal Syntax
> 
> 
> And one question: what is semantics of value type variable assignments.
> ValType v=...;
> ValType v2 = v;
> Is v2 new value instance?

given v is a value type, i.e. a non mutable identity-less value, let say it's the same value.

Rémi

> 
> 
> On Tue, Feb 27, 2018 at 1:16 AM, John Rose <john.r.rose at oracle.com> wrote:
> 
>> 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.
>>
>> - disallow (the decision we made)
>> - turn single level assignment into withfield, disallow others
>> - allow multiple-level assignment to resolve to subfield descriptors
>> - generate nested dup;getfield;…;withfield sequences
>> - make field assignment a distinct API point
>>
>> 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
> 
> 
> 
> 
> --
> 
> Best Regards,
> Ali Ebrahimi


More information about the valhalla-dev mailing list