Bitten by the lambda parameter name

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


On Wed, Jul 17, 2013 at 4:25 AM, Maurizio Cimadamore
<maurizio.cimadamore at oracle.com> wrote:
> On 17/07/13 03:15, Zhong Yu wrote:
>>
>> "for(s : s)" doesn't make sense if read out loud in English; nobody
>> wants to write a line like that, so I'm confused why it drives
>> Maurizio crazy that it's illegal.
>
> This is _legal_ !!!
>
> If s is a field then you can legally refer to s from the for-each
> expression, as the JLS says that the for-each variable is _not_ in scope
> there.
>
> Where I'm getting at, is that every rule as its pros and its cons; when
> talking about scoping, I'd rather staying on the safe side and (physically,
> if required :-)) prevent people from writing stuff like:
>
> m(ping, ping -> pong, pong)

how should people write this code?

    m(ping, ping2->pong, pong)?

>
> Will this be too strict in other interesting cases? Of course - but I think
> the risk that we will end up with a mess of unreadable code is not to be
> undertaken.

We also need to trust people a little bit. Java has a high degree of
freedom for overloading names,

class A<A>  // one name for 7 different things
{
    A A;
    A A(){ return A; }
    <A> A A(A A){ return A; }
}

but somehow Java programmers survived the freedom... By induction I
think we'll also be fine to allow lambda parameter names shadowing
local variables.

Zhong Yu


>
> Maurizio
>
>>
>> If it is meant to ridicule the feature request by presenting an
>> example that goes horribly wrong, it is not a fair/realistic example
>> to prove the point. It's like arguing Java's rules of names are too
>> lax because people might write incomprehensible code like
>>
>> class _
>> {
>>      _ _;
>>
>>      _ _(){ return _; }
>> }
>>
>>
>>
>> Zhong Yu
>>
>>
>> On Tue, Jul 16, 2013 at 7:44 PM, Jonathan Gibbons
>> <jonathan.gibbons at oracle.com> wrote:
>>>
>>> On 07/16/2013 04:59 PM, Zhong Yu wrote:
>>>>
>>>> On Tue, Jul 16, 2013 at 6:48 PM, maurizio cimadamore
>>>> <maurizio.cimadamore at oracle.com> wrote:
>>>>>
>>>>> On 17-Jul-13 12:37 AM, Zhong Yu wrote:
>>>>>>
>>>>>> I don't think people have problems to keep track of scope stacks and
>>>>>> associate a name with its closest definition. Do we have testimonies
>>>>>> of confusions from other languages that allow reusing local names in
>>>>>> lambda parameters?
>>>>>
>>>>> Speaking about Java, there is a scoping rule that drives me crazy, and
>>>>> it's
>>>>> the one for the for-each loop; it should be legal to say:
>>>>>
>>>>> Collection<String> s = ...
>>>>> for (String s : s) {
>>>>
>>>> I don't know if you are being sarcastic or not, but `for(s : s)` does
>>>> not make any sense to me... something that contains itself?
>>>
>>> In "for (String s: s)" the presumption would be that the second s
>>> would refer to the collection defined on the previous line, and not
>>> the foreach variable itself, since (as you point out) that would not
>>> make any sense.
>>>
>>>
>>>> But here's an example that I think does make sense and shoulda compiled
>>>>
>>>>           String string = ...;
>>>>           ...
>>>>           List<String> strings = ...;
>>>>           for(String string : strings)  // reuse "string"
>>>>               ...
>>>>
>>>>> ...
>>>>> }
>>>>>
>>>>> This example features the same kind of disambiguation pattern that I've
>>>>> seen
>>>>> applied in most examples here - stuff on the left of the ':' (or '->')
>>>>> has
>>>>> one meaning, stuff on the right has another meaning.
>>>>>
>>>>> The only example I would be more comfortable with, is the last one you
>>>>> sent,
>>>>> where you use the same parameter name in two different nesting levels.
>>>>> This
>>>>> is slightly different from what we have discussed so far.
>>>>>
>>>>> Maurizio
>>>>>
>>>>>> On Tue, Jul 16, 2013 at 6:25 PM, maurizio cimadamore
>>>>>> <maurizio.cimadamore at oracle.com> wrote:
>>>>>>>
>>>>>>> On 16-Jul-13 11:59 PM, Remi Forax wrote:
>>>>>>>>
>>>>>>>> On 07/17/2013 12:40 AM, maurizio cimadamore wrote:
>>>>>>>>>
>>>>>>>>> On 16-Jul-13 11:17 PM, Dan Smith wrote:
>>>>>>>>>>>
>>>>>>>>>>>      StringBuilder builder = createText(StringBuilder.class,
>>>>>>>>>>> builder
>>>>>>>>>>
>>>>>>>>>> -> builder.append("name"));
>>>>>>>>>
>>>>>>>>> What is this meant to replace exactly? It's a shorthand for:
>>>>>>>>>
>>>>>>>>> StringBuilder builder = new StringBuilder();
>>>>>>>>> builder.append("name");
>>>>>>>>>
>>>>>>>>> ?
>>>>>>>>>
>>>>>>>>> Maurizio
>>>>>>>>
>>>>>>>> Again, I'm not sure why this is interesting to know exactly what the
>>>>>>>> code does,
>>>>>>>> Anyway, the code of createText allows you to create a mutable object
>>>>>>>> by reflection, to initialize it and when you get the result,
>>>>>>>> you have the guarantee that you can never see the object half
>>>>>>>> initialized.
>>>>>>>
>>>>>>> I'm asking about the code, because I think that if we are forcing
>>>>>>> people
>>>>>>> to write code like that there might be a problem other than the scope
>>>>>>> issue.
>>>>>>> Having two variables so close with the same name is confusing - no
>>>>>>> matter how the language will pan out in the end. YOu seem to imply
>>>>>>> that
>>>>>>> using the same name is justified by the fact that the two objects are
>>>>>>> really the same - but I'm less sure that many people will be able to
>>>>>>> read your code and immediately grasp as to why the two variables are
>>>>>>> named in the same way. I think a good API should minimize occurrences
>>>>>>> of
>>>>>>> that for the users sake.
>>>>>>>
>>>>>>> Maurizio
>>>>>>>>
>>>>>>>> Rémi
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>
>


More information about the lambda-dev mailing list