Comments on JDK-8198408 please ?

Maurizio Cimadamore maurizio.cimadamore at
Tue Feb 27 00:50:10 UTC 2018

On 27/02/18 00:36, John Rose wrote:
> On Feb 26, 2018, at 4:00 PM, Maurizio Cimadamore 
> <maurizio.cimadamore at 
> <mailto:maurizio.cimadamore at>> wrote:
>> ...We should have a lowering step before getting to the backend which 
>> prepares the AST to a form which is more amenable to the withfield 
>> treatment. So if you have
>> a.b.c = x
>> this should be translated as:
>> __WithField(a.b, __WithField(b.c, x))
> More precisely:
> a = __WithField(a.b, __WithField(a.b.c, x))
Right - that's more explicit - and better
> The first __WithField returns an updated version of a (with b updated).
> The second returns an updated version of a.b (with c updated).
> And the whole thing needs to be written back to a.
> And, I'd prefer if the programmer were forced to write the __WithFields
> explicitly, since it's closer to the virtual machine.
>> and the backend should then have an easier life. Incidentally, this 
>> form is also similar to what John suggested to use as a prototype - 
>> so perhaps a new experimental keyword and a new experimental AST node 
>> could be a good start here.
> +1
>> Once we have a new AST node - e.g.
>> class JCWithField extends JCExpression {
>>    JCExpression lvalue;
>>    JCExpression rvalue;
>> }
>> We have to decide what kind of 'lvalue' are admissible in such a 
>> construct. How many levels can the lvalue have? Can the lvalue 
>> contain complex expressions, as in:
>> __WithField(foo(x -> ...).g, 12)
> I don't think complex LHSs are a problem for __WithField.  The only 
> "magic" structure
> in the LHS is the trailing ".g".  The stuff before ".g" is just a 
> pointer expression.
> It gets code generated like this:
>    …stuff before ".g" compiled to TOS
>    invokestatic foo(Function)Foo
>    bipush 12
>    withfield Foo.g:int
>    …result is at TOS
>> I think for now it's better to start simple - only one level allowed 
>> and no complex expressions in the selector allowed.
> I don't think there is really a technical reason for this; but of 
> course is there is one,
> make it simpler by restricting the construct.
I agree there's no technical reason to have the restriction - and I did 
not propose the restriction because of that - I was only putting that 
restriction forward to allow for a 'staged' prototype - e.g. we can 
start simple, and add more complex forms as we go, and as we see fit.

And no - I did not want an implicit write-back - if user wants writeback 
it should do that explicitly:

A a = _WithField(a.x, 11);

>> That means that lvalue should be restricted to a JCFieldAccess node, 
>> whose 'selected' part must be a JCIdent. This form should be close 
>> enough to what the bytecode can handle.
> I think, the reason you are suggesting this is you are envisioning a 
> "magic"
> write-back of the JCIdent variable, under the hood.  I am not, which 
> is why
> I corrected your formula above to include an explicit write-back.
> The __WithField op should be exactly a withfield bytecode, no more and
> no less.  If the user wants a writeback, then write back the new value.
> Otherwise, send it somewhere else (field write, method arg, etc.).
> Oh, and __WithField is an expression operator, but *not* a statement
> expression operator.  It's like +-*/&|^ (and I mean that in the nicest 
> way).
>> This means that some 'manual' desugaring would need to take place - 
>> but I think it's an acceptable trade off for now.
> Asking the user to do the write-back is the best manual desugaring!
> — John

More information about the valhalla-dev mailing list