recursive lambda as a local variable

Zhong Yu zhong.j.yu at gmail.com
Wed Sep 11 11:04:22 PDT 2013


On Wed, Sep 11, 2013 at 12:54 PM, Remi Forax <forax at univ-mlv.fr> wrote:
> On 09/11/2013 07:32 PM, Zhong Yu wrote:
>> State of the Lambda seems to suggest that this can be done for local variables:
>>
>> http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html
>>
>>> When a lambda expression appears in any other context, such as a return expression, there is no way for it to refer to itself. The proper approach in such cases is to name the object with a variable declaration and replace the original expression with a variable reference.
>
> This can be done, everything can be done with a computer,
> but it means initializing a lambda that capture a reference to itself.
> So you may observe a state where the lambda is not fully initialized,
> in between.

but the lambda body can never be invoked before the lambda is fully
initialized, correct? so it should be safe.

in contract, the method body of an anonymous class could be invoked
before the object is fully initialized.

>
> And you can also use a method reference instead of a lambda
>    static void run() {
>      run();
>    }
>    Runnable r = Foo:run;
>
> To summarize,this construct solves a corner case that is painful to
> implement,
> and hard to get right so it was rule out by the EG.
>
> Rémi
>
>   On Wed, Sep 11, 2013 at 12:16 PM, Brian Goetz <brian.goetz at oracle.com>
> wrote:
>>> Its not so much "intentional" as a consequence of language rules that
>>> predate lambda.
>>>
>>> In the first example, r is a field; in the second, it is a local.  What the
>>> first lambda really is shorthand for is:
>>>
>>>      Runnable r = () -> this.r.run();
>>>
>>> So this lambda captures 'this', whereas the second lambda captures 'r'.  The
>>> latter runs into definite-assignment issues, but fields are not subject to
>>> assignment and flow analysis.
>>>
>>> Of course, when you use 'this' from the initializer of a field, you are on
>>> thin ice.
>>>
>>>
>>> On 9/11/2013 12:37 PM, Zhong Yu wrote:
>>>> This compiles: (b106)
>>>>
>>>>       class Test
>>>>       {
>>>>           Runnable r = ()->r.run();
>>>>       }
>>>>
>>>> but this doesn't:
>>>>
>>>>       void test()
>>>>       {
>>>>           Runnable r = ()->r.run();
>>>>       }
>>>>
>>>> is that intentional or a bug?
>>>>
>>>> Zhong Yu
>>>>
>
>


More information about the lambda-dev mailing list