Implicit lambda names

I meant, my issue was a non-issue.

I added some ideas mentioned here.

I think that it is a good idea to write there a summary of this discussion.

@HughG this message is for you too, I suppose.

I’m not sure on which thread to continue the discussion so I’ll add more detail here and maybe someone can re-summarise on the other thread if we get to any new conclusions.

I was thinking that the syntax we’d brainstormed was getting a bit ugly when all cases were considered, so I thought I’d dig for the real requirement, which I think is, “have a more concise syntax for lambdas”.

Then I thought, rather than having implicit declaration, could we have it be explicit but not repetitive (declaration plus maybe only one use). How about you use some short token to mark a single variable within the body of the lambda, as a shorthand for declaring that variable as the single lambda parameter? For argument’s sake I’ll pick \>, though I don’t love that. With that, your original example becomes as follows.

ArrayList<Student>()
    .filter { \>student.schoolId % 2 == 0 }
    .filterNot { \>person.id == 0 }
    .map { \>familyMember.parent.toUpperCase() }

This has several advantages.

  • No developer confusion about which variable is the lambda parameter.
  • No ambiguity for overloads taking zero-argument lambdas.
  • Usual variable shadowing rules apply, so no surprises if names in the surrounding context change.

I’m intentionally not covering destructuring of the single argument, nor multiple arguments, because the only syntax I can vaguely imagine for those (something involving numbers as indexes) would definitely be confusing and hard to maintain. (I’m thinking of my experience of languages or frameworks which have string formatting using numeric indexes.)

1 Like

Is this narrowed feature useful enough to implement it?

I’m not sure how it’s narrower than your original proposal. Can you give me an example which your original idea covers and mine doesn’t? To be clear, I’m allowing the variable which is prefixed with the magic token could appear in any position in the lambda body, not only at the start. If it appears more than once, it must only be prefixed the first time.

Oh, now I see, what you mean. That is not narrower, but it has another problem: what if I decide to remove my first entry? Then I have to find the next entry. This looks weird.

Hmm, actually it’s worse than just awkward: other mentions of the removed variable might become uses of a name from an outer scope (if the variable had been shadowing such a name). So I suppose all uses of the variable need the magic token, which is less concise but maybe easier to understand.

In that case, what is the advantage over just defining the name for the lambda parameter the same way you do right now? If every usage needs some special token, why add this special case for lambdas. It will just mean that lambdas have a very strange looking way of defining 1 special value. Also this only works for lambdas with 1 parameter making this even weirder.
I see the original problem this is trying to solve, but I don’t think adding a strange special case is the way to go.

2 Likes

So that is what is written in another topic, I mentioned.

If so, what is your idea for that?

Not replying to the general proposal, but wanted to point out that sometimes in simple cases using a function reference instead of lambda can be a better alternative:

        .forEach(Person::run)
2 Likes