Why were single-line lambdas removed?

Looking through old PRs I found this Change `fewerBraces` to support inline lambdas after `:` by odersky · Pull Request #15258 · scala/scala3 · GitHub

odersky commented on May 21, 2022 •
So it’s

  xs.map: x =>
      x + 1
    .foldLeft: (x, y) =>
      x + y

Now also possible:

  xs.map: x => x + 1
    .foldLeft: (x, y) => x + y

It was possible to write xs.map: x => x + 1, no newline required.

This looks nice, why was it deprecated? Are there any preserved discussions I can read to understand the decision to remove it? I’m looking through related comments on github, but it’s a bit hard understanding bit-by-bit out of context. All I’ve seen is that it looks similar to type ascriptions. Was that the only reason?

Really? When was this? (what Scala version) I must have missed it. It was probably briefly available?

I don’t really understand the problem with xs.map(x => x + 1) to be honest. Even if you hate and want to abandon all braces, parentheses are not braces…

2 Likes

Odersky comment in the contributors thread, at the time of those PRs about “inline” (i.e. “one-line”) lambdas:

A few posts later he says:

In other words, fewerBraces is about dropping braces, not parentheses.

See previous message by Jasper-M.

Seb comment earlier in the thread, which re-activated it. The PR about lambdas was about requiring colon, which was absent before, and that was the version Seb was responding to.

Besides aesthetics, the deciding factor against one-line lambdas was disambiguation, because the parser must look at the rest of the line to decide what it is. I think having lambda params on the same line is already a pretty good trick.

There is a post asking for one-line lambda syntax near the beginning of the thread, from a year previous.

It is a rich thread well worth reading. covering pedagogy and more thoughts about significant indentation and challenges to migration. However, no conclusion was reached as to the optimal indentation width for Scala, except that it falls in the range 2..4.

The link is to a PR that was not merged.

When they write the simple examples, I want it.

I’m a fan of one-line catch, and I’d also like one-line match.

We know that LOC represents technical debt (for a given bug rate), so that having more constructs that encourage one-liners will necessarily reduce bugs.

The ad copy writes itself.

3 Likes

:rofl:

Single-line lambdas with : were never implemented. To do this we’d have to solve some ambiguity problems in the syntax which look hard. I think it might be worth trying this, but right now I have other priorities.

2 Likes

There’s not a problem with that example, xs.map: x => x + 1 and xs.map(x => x + 1) are equal in readability. The problem is inconsistency, it’s nice to not mix notations throughout a codebase.

If I start with a one-liner, I don’t mind the parentheses, but it occasionally bites me when I go from:

XS.map: x =>
   ... // lengthy code

to

XS.map: x =>
   ... // shorter code

to

XS.map: x => ... // short code

and now have to add parentheses.

2 Likes

That just happened to me! This “refactoring” case was mentioned a few times in the discussions.

One may ask how often does one do that.

My experience was a line of debug, where I wanted it single-line so that I could more easily comment it out. (Without firing up an IDE to do “block commenting-out”.)

res
  .tap: v => println(v)

The other footnote is that one can refactor the other way:

xs.map:
  x => f(x)
1 Like

It turns out we can actually make it work: Allow single-line lambdas after `:` by odersky · Pull Request #23821 · scala/scala3 · GitHub.

10 Likes

There’s now a Pre-SIP discussion for the new feature on Contributors.

1 Like