Bitten by the lambda parameter name

Remi Forax forax at univ-mlv.fr
Wed Jul 17 02:37:54 PDT 2013


On 07/17/2013 11:28 AM, Maurizio Cimadamore wrote:
> On 17/07/13 09:48, Remi Forax wrote:
>> On 07/17/2013 01:29 AM, Zhong Yu wrote:
>>> It creates a dilemma for API designers. In this case Doug Lea chooses
>>> efficiency, at the cost of annoying user Remi Forax.
>>>
>>> Programmers would love to reuse simple names. Here's an example that
>>> seems pretty reasonable, note the two "event" variables
>>>
>>> buttonA.onClick(event->{
>>>       ...
>>>       buttonB.enable();
>>>       buttonB.onClick(event->{ form.submit(); })
>>> });
>>>
>>> Zhong Yu
>> yes, this one is a also good example of why a lambda parameter should
>> hide a local variable.
> Except, here there's no local variable hiding - you have two nested 
> lambdas, where the parameter of one hides the parameter of the other. 
> If you wrote a rule specifically targeting this example, you would 
> soon find out that you'll still be stuck with your original 
> computeIfAbsent example.
>
> Maurizio

I use 'local variable' as a broader term, for parameter, real local 
variable, exception parameter, etc.

Rémi

>>
>> Rémi
>>
>>>
>>>
>>> On Tue, Jul 16, 2013 at 3:20 PM, Dan Smith <daniel.smith at oracle.com> 
>>> wrote:
>>>> On Jul 16, 2013, at 9:20 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>>>>
>>>>> On 07/16/2013 05:05 PM, Maurizio Cimadamore wrote:
>>>>>> On 16/07/13 16:00, Peter Levart wrote:
>>>>>>> Perhaps here, an overloaded Map.computeIfAbsent that takes a 
>>>>>>> Supplier
>>>>>>> instead of Function would be handy. Even when you need the key to
>>>>>>> construct new value, it is usually ready in some effectively-final
>>>>>>> variable in the scope. And when you don't need the key, a 
>>>>>>> constructor
>>>>>>> reference could be applied like:
>>>>>>>
>>>>>>> partySetMap.computeIfAbsent(kind, HashSet::new).add(...);
>>>>>> +1
>>>>>>
>>>>>> I think the underlying problem to this discussion might be that 
>>>>>> there
>>>>>> are places (and computeIfAbsent seems to be one of them) where the
>>>>>> lambdi-fication of the library took a somewhat convoluted path, in
>>>>>> which the 'same' variables needs to be supplied multiple times in
>>>>>> order to keep the chain happy (which then turns out to be 
>>>>>> problematic
>>>>>> because of scoping rules).
>>>>> There is a big difference, if you provide the key as parameter the
>>>>> lambda will be a constant so the cost of using it is 0
>>>>> (if you forget the initialization cost), if you don't provide the 
>>>>> key as
>>>>> parameter, you will need to capture it and in that case, the runtime
>>>>> will create a fresh lambda for each call.
>>>> So this amounts to a language feature request to facilitate a 
>>>> performance optimization.  You'd like to avoid capture by using a 
>>>> pattern that relies on re-declaring variables for identical values, 
>>>> because capture is less efficient.  Thus, you wish the language 
>>>> were more friendly to re-declarations.
>>>>
>>>> In such situations, it's appropriate to ask: is this the tail 
>>>> wagging the dog?  Capture is the _right_ way to express what's 
>>>> going on, even if it's less performant.  Right?
>>>>
>>>> I wonder if the efficiency problem will be optimized away someday.  
>>>> Maybe with value types, the VM could avoid boxing up the capture 
>>>> variables with the underlying function?
>>>>
>>>> —Dan
>>>>
>>>>
>>
>



More information about the lambda-dev mailing list