Bitten by the lambda parameter name

Zhong Yu zhong.j.yu at gmail.com
Fri Sep 6 15:17:58 PDT 2013


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