Bitten by the lambda parameter name
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Jul 17 02:28:00 PDT 2013
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
>
> 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