Bitten by the lambda parameter name
peter.levart at gmail.com
Tue Jul 16 08:40:53 PDT 2013
On 07/16/2013 05:20 PM, Remi Forax 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(...);
>> 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.
That's true. And if there was an overload taking Supplier, users could
use this one, rather than the one taking Function, not being aware that
they're paying the price. To bad.
>> In my eyes, computeIfAbsent also looks a bit off - i.e. wouldn't it
>> be useful to provide an option to fill in default values for absent
>> keys at map construction rather than at call site?
> computeIfAbsent, put the computed value in the Map if the couple
> key/value doesn't exist,
> thus computeIfAbsent is useful when using a Map as a cache.
The Function that computes the value for the key could be supplied at
Map creation time. But that's also the problem, since computeIfAbsent
(or any such method) is a default method which is expected to work for
any Map implementation...
> The method that provide a default value is getOrDefault and yes, it's
> often better to send the default value when creating the Map,
> because the default value usually doesn't change but at the same time,
> storing a default value like Collections.emptySet() in each map is not
> very memory efficient.
Could be efficiently stored in the Map like other entries (using special
private key), but the same problem exists like with computeIfAbsent.
Such default method could only work with "cooperating" Map
implementations and not with any Map...
More information about the lambda-dev