Bitten by the lambda parameter name
Zhong Yu
zhong.j.yu at gmail.com
Fri Sep 6 17:20:36 PDT 2013
There are probably a lot of anonymous classes in the wild with lengthy
method bodies that contain local variables. Automatic conversion to
lambda expression may be hindered by this kind of naming conflicts.
Interestingly IntelliJ is smart enough to withhold the auto conversion
if such naming conflict exists.
Zhong Yu
On Fri, Sep 6, 2013 at 5:36 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> True. But also realize that lambdas that declare locals are already veering
> into corner-case territory. I did a quick search through lambda expressions
> in the JDK source base (which is a significant fraction of the lambda
> expressions in Java code worldwide, at this point), and found NO instances
> of lambdas that declare locals.
>
> I'm not saying it can't or won't happen, I'm saying it will be rare. So,
> this "but its also an issue for local variables in lambdas" argument doesn't
> really change the balance on this subject at all. Next case!
>
>
>
> On 9/6/2013 6:17 PM, Zhong Yu wrote:
>>
>> Note that this problem does not only exist for lambda parameters, but
>> also for local variables in lambda body, apparently from the same
>> rationale.
>>
>> void test()
>> {
>> int x = 0;
>>
>> Runnable r = ()->{
>> int x = 1; // error: variable x is already defined
>> };
>> }
>>
>> I would imagine that people are going to use deeply nested lambda
>> expressions, e.g. a DSL to define an html tree. This restriction is
>> going to become an inconvenience.
>>
>> Perhaps the restriction can be limited to implicit lambda parameter
>> only; explicit lambda parameter and lambda body variable have less
>> chance of causing confusion because of the full form of declaration.
>>
>> void test()
>> {
>> String s = null;
>> int x = 0;
>>
>> Consumer<String> consumer = (String s)->{
>> int x = 1;
>> };
>> }
>>
>> Back to Remi's original example, if we use explicitly typed parameter
>>
>> Kind kind = ...
>> map.computeIfAbsent(kind, (Kind kind)->{...});
>>
>> it looks pretty clear that a function object is being defined; readers
>> are unlikely to confuse `kind` the method parameter with `kind` the
>> local variable (which is
>> Stephen Colebourne's point)
>>
>> Zhong Yu
>>
>> On Thu, Jul 18, 2013 at 5:34 PM, John Rose <john.r.rose at oracle.com> wrote:
>>>
>>> On Jul 17, 2013, at 9:48 AM, Zhong Yu <zhong.j.yu at gmail.com> wrote:
>>>
>>> I personally don't think it's a strong enough case; when I read
>>> x->++x, I'll see this is a new x, and the new x is being incremented.
>>>
>>>
>>> Many of the Java language safety rules (including local shadowing rules)
>>> are
>>> not designed for the people on this mailing list. They are designed for
>>> the
>>> other 99% of programmers, who are not so eager to process language corner
>>> cases. And shadowing, however natural its logic is, gets experienced as
>>> a
>>> corner case, often enough to cause bugs in the field. (No I don't have
>>> survey numbers.)
>>>
>>> The value of anti-shadowing rules is less when declarations are more
>>> visible
>>> and/or can be placed in fewer syntactic locations. This is why class
>>> members can participate in shadowing: Class members generally occupy
>>> their
>>> own lines of code. Parameters and locals are often declared inside other
>>> constructs (method headers, for loops), so they are harder to see.
>>> Therefore, multiple competing definitions of these constructs are more
>>> confusing. Guess which category lambda parameters fall in? Hint: A
>>> lambda
>>> parameter declaration can be one token long, and embedded in an
>>> expression.
>>>
>>> So, regardless of how it outrages syntax-savvy users, I think it is
>>> better
>>> to forbid having lambda parameters participate in shadowing.
>>>
>>> The two proposed use cases of (foo) -> (expr_not_containing_foo) seem
>>> especially wrong-headed to me. Why *must* we allow users to have the
>>> exact
>>> name "foo", for a variable that isn't even used? Because it is so
>>> important
>>> to insert a clever comment that the formal parameter "foo" (though
>>> unused)
>>> is known to the programmer to have the same value as an uplevel variable
>>> named "foo"? There are other ways to comment code than choose a name for
>>> an
>>> unused variable!
>>>
>>> — John
>>
>>
>
More information about the lambda-dev
mailing list