Bitten by the lambda parameter name

Zhong Yu zhong.j.yu at gmail.com
Wed Jul 17 09:48:21 PDT 2013


On Wed, Jul 17, 2013 at 5:19 AM, Alessio Stalla <alessiostalla at gmail.com> wrote:
> On Wed, Jul 17, 2013 at 11:47 AM, Stephen Colebourne
> <scolebourne at joda.org> wrote:
>> On 15 July 2013 15:52, Remi Forax <forax at univ-mlv.fr> wrote:
>>> This snippet not compile,
>>>    Kind kind = ...
>>>    partySetMap.computeIfAbsent(kind, kind -> new HashSet<>()).add(party);
>>>
>>> Each time I write more than a hundred lines of codes that use some lambdas,
>>> I fall into this trap.
>>>
>>> It's very annoying !
>>
>> Just to note that it is correct that this not compiling. It should be
>> viewed from the perspective of a code reader, not a code writer.
>>
>> There is no visible additional scope here, just an expression like any
>> other. As a reader (without any further knowledge, including knowledge
>> about lambdas) I'd expect that expression to have no additional scope,
>> just like the ternary operator has no additional scope.
>>
>> Note that a different syntax would have affected this:
>>
>>   partySetMap.computeIfAbsent(kind, #(kind) {new HashSet<>()}).add(party);
>>
>> In this case, there is something that looks a lot more like an inner
>> class and a method, in which case I'd expect the method parameter to
>> have a different scope.
>>
>> The borderline case is
>>   partySetMap.computeIfAbsent(kind, (kind) -> new HashSet<>()).add(party);
>>
>> where there is something that looks vaguely like a method parameter.
>> But I don't think its enough to convince me that the parameter should
>> be in a different scope.
>>
>
> I disagree, I don't think that surface syntax has anything to do with scope.
> lambda x: x in Python and (lambda (x) x) in Lisp both introduce a
> scope where x is lexically bound, even if their syntax differences are
> quite important.
>
> Scope is closely related to binding; does a lambda expression
> introduce a binding for its parameters in its body? Yes. Then it would
> be sane to scope those parameters lexically within the lambda.
> Otherwise a simple refactoring (like the renaming of a lambda
> parameter or even of a local variable far above!) might break
> previously working code. Even JavaScript, whose scoping is quite
> brain-damaged, gets this right!
>
> That users might write bad code like foo(x, x -> x + 1, () -> x) is
> not a good reason for subverting scoping rules. Users will still be
> able to write code like foo(x, x2 -> x2 + 1, () -> x) which is almost
> equally bad. You cannot prevent users from choosing poor variable

The `x2` version is slightly less bad. I remember there was a
discussion about this code

    int x = ...;
    ...
    foo( x->++x );

which is kind of confusing - writer or readers of the code might
mistakenly think that the local variable will be incremented.
Forbidding `x` as lambda parameter can avoid this kind of
mistakes(i.e. attempting to mutate a local variable from a lambda
body). 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.

Zhong Yu




> names.
>
> This is my opinion.
>
> Alessio
> --
> Some gratuitous spam:
>
> http://ripple.com Ripple, social credit system
> http://common-lisp.net/project/armedbear ABCL, Common Lisp on the JVM
> http://code.google.com/p/tapulli my Lisp open source projects
> http://www.manydesigns.com/ ManyDesigns Portofino, open source
> model-driven Java web application framework
>


More information about the lambda-dev mailing list