recursive lambda as a local variable

Gernot Neppert mcnepp02 at googlemail.com
Thu Sep 12 10:02:29 PDT 2013


Well, "nice" is, of course, subjective, so I won't argue about that.
But while an Unbound Method Reference is very helpful in reducing the 
syntactial "noise" by getting rid of the argument declaration -

'Customer::getOrders' vs. 'c -> c.getOrders()'

- using BMRs does not have this effect, if used with a typical unary 
functional expression:

'id -> customerDao::getCustomer(id)' vs. 'id -> customerDao.getCustomer(id)'

Here, the left side seemingly introduces a new syntax for the dot 
operator for no obvious reason (but with a couple of subtle pitfalls, as 
I pointed out previously).
The :: operator is new in Java, so we can easily restrict its meaning to 
"Class::method"!

Am 12.09.2013 16:58, schrieb Zhong Yu:
> On Thu, Sep 12, 2013 at 8:00 AM, Gernot Neppert <mcnepp02 at googlemail.com> wrote:
>> The line
>> Runnable r2 = this.r2::run;
>>
>> from you examples shows one thing clearly: Bound Method References (BMRs)
>> are questionable at best, dangerous at worst.
>> Some quirky things about BMRs:
>>
>> - The part left of the '::' can be an arbitrarily long expression that will
>> be evaluated immediately, while the method invocation itself will be
>> deferred until the corresponding SAM method is invoked. Thus, 'null' might
>> by bound now and detected much later.
>>
>> - Due to the early binding/late execution issue, BMRs are confusingly
>> different from their plain lambda counterparts: 'this.r2::run' is very
>> different from '() -> this.r2.run()' because r2 might be assigned later.
>>
>> - BMRs will usually neither save much typing nor be better readable than a
>> corresponding plain lambda expression.
> I disagree based on my own experience. I use it *a lot* and it does
> look nice. And in all my usages of `expr::method`, `expr` is a
> (effective) final variable.
>
>> Note that all of the above points are _not true_ with regards to Unbound
>> Method References, (e.g. String::valueOf or Pojo::getName), which I'd
>> consider a very useful addition to the lambda universe!
>>
>> So, should we get rid of BMRs? ;-)
>>
>>
>>
>>
>> 2013/9/11 Zhong Yu <zhong.j.yu at gmail.com>
>>> On Wed, Sep 11, 2013 at 12:36 PM, Dan Smith <daniel.smith at oracle.com>
>>> wrote:
>>>> I'm pretty sure that's just the way things work.
>>>> Fields can refer to themselves in their initializers;
>>>
>>> With lambda it is more confusing
>>>
>>> public class Tmp
>>> {
>>>      Runnable r1 = ()->r1.run(); // ok
>>>
>>>      Runnable r2 = this.r2::run; // compiles... but
>>> NullPointerException at runtime
>>> }
>>>
>>> Zhong Yu
>>>
>>>
>>>
>>>
>>>> local variables cannot.  (This is because fields always have a value
>>>> (possibly null), while local variables can't be accessed before
>>>> initialization.)
>>>>
>>>> You could try the same thing with an int:
>>>>
>>>> int i = i+1;
>>>>
>>>> —Dan
>>>>
>>>> On Sep 11, 2013, at 10:37 AM, Zhong Yu <zhong.j.yu at gmail.com> 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