[External] : Re: This expression in lambda in early construction context

Archie Cobbs archie.cobbs at gmail.com
Fri Jun 7 22:10:22 UTC 2024


I think Ella may have a valid point from the point of view of the
specification - i.e., where in the new spec does it specify that the new
LHS field assignment exception doesn't apply within a lambda?

§6.5.6.1 says:

If the expression name appears in an early construction context of C
> (8.8.7.1), then it is the left-hand operand of a simple assignment
> expression (15.26), and the declaration of the named variable lacks an
> initializer.


But the definition of early construction context includes all contained
lambdas, subclasses, etc.

So maybe it should instead say something like:

If the expression name appears in an early construction context of C
> (8.8.7.1), then it is the left-hand operand of a simple assignment
> expression (15.26), the declaration of the named variable lacks an
> initializer, and the expression is not contained in any lambda or class
> declaration that is contained in C.


-Archie

On Fri, Jun 7, 2024 at 4:35 PM Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

> Hi Ella,
> the problem here is that, since the lambda needs to refer to "this", it's
> as if you need to pass "this" to create the lambda object.
>
> To make it simpler, you can think of the lambda as a local class (not
> entirely accurate, but I think it paints a good analogy for what's going on
> here):
>
> class Main {
>     int a;
>     Main() {
>         this.a = 1; //line A
>         class Foo {
>               Main this$0;
>               Foo(Main this$0) { this.this$0 = this$0; }
>               void run() { this$0.a = 1; }
>         }
>         Foo lmb = new Foo(this); // line A
>
>         lmb.run(); //line B
>         super();
>     }
>
>
> Like before, in line (A) we create the lambda expression (here modelled as
> a local class). Note that the local class wants a construction parameter,
> of type Main (since the local class needs to refer to it). But then, in
> line (B), we need to supply an argument of type Main, namely "this". So
> here we are effectively reading/accessing "this" before the super
> constructor has been called.
>
> The lambda expression, being so compact, hides a bit of the problem and
> you are right that it's a bit confusing at first, but I hope the example
> above clarifies things a bit.
>
> Cheers
> Maurizio
> On 05/06/2024 22:29, Ella Ananeva wrote:
>
> Thanks for pointing this out, Chen.
>
> Please bear with me for a moment. If we have a lambda as a local variable
> in the constructor, it cannot be invoked outside of the constructor, right?
>
>
>
> class Main {
>     int a;
>     Main() {
>         this.a = 1; //
> *line A         *Foo lmb = () -> this.a = 1;
>
>         lmb.foo(); //line B
>         super();
>     }
>
>

-- 
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240607/7f76e9b6/attachment-0001.htm>


More information about the amber-dev mailing list