Bitten by the lambda parameter name
Brian Goetz
brian.goetz at oracle.com
Fri Sep 6 15:36:47 PDT 2013
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