Skip to content

Conversation

@odersky
Copy link
Contributor

@odersky odersky commented Aug 26, 2025

Previously, we need to indent after the arrow, e.g.

xs.map: x =>
  x + 1

We now also allow to write the lambda on a single line:

xs.map: x => x + 1

The lambda extends to the end of the line.

This is a trial balloon to see whether anything breaks. If we want to pursue this it needs a SIP.

@soronpo
Copy link
Contributor

soronpo commented Aug 27, 2025

Will it also work for self types?

trait Foo: self =>
end Foo

@lihaoyi
Copy link
Contributor

lihaoyi commented Aug 27, 2025

I wonder if xs.map: case Some(x) => x + 1 could be made to work as well?

@som-snytt
Copy link
Contributor

The case for case is at #22016. I think the parens SIP opens the floodgates of consistency.

@lihaoyi
Copy link
Contributor

lihaoyi commented Aug 29, 2025

@odersky
Copy link
Contributor Author

odersky commented Aug 29, 2025

if we need a SIP for this, maybe we could fold it into https://contributors.scala-lang.org/t/sip-xx-allow-partial-function-literals-to-be-defined-with-parentheses/7207/16

Yes, I think the two go well together. This PR now also implements the single-case version of sip-xx. I have some reservations against admitting multiple cases between parentheses. I'll explain more on the SIP.

@odersky
Copy link
Contributor Author

odersky commented Aug 29, 2025

Will it also work for self types?

Right now, no. I'd like to re-think self types in general. So I'm not keen on fiddling with them until that's done.

@GLI-RK0
Copy link

GLI-RK0 commented Aug 29, 2025

Awesome. Will this extend to lambdas with by-name parameters and/or context parameters?

You can currently write

// after delay, execute fn
def delay(ms: Double)(fn: => Unit) = ???

delay(300):
  println("hello")

Will we also be able to write

def delay(ms: Double)(fn: => Unit) = ???

delay(300): println("hello")

and

def delay(ms: Double)(fn: (timestamp : Double) ?=> Unit) = ???

delay(300): println(s"time ${timestamp}")

?

@odersky odersky force-pushed the one-line-colon-lambda branch from b8b6a68 to e4a53c6 Compare August 29, 2025 13:18
@odersky
Copy link
Contributor Author

odersky commented Aug 29, 2025

Awesome. Will this extend to lambdas with by-name parameters and/or context parameters?

Currently, no. We should discuss what we want. Some choices:

  1. no extension to by-name or context-parameters
  2. allow : syntax for these parameters only
  3. allow : syntax for all arguments.

Possible reason for (2): The situation is similar to single-line-lambdas with parameters.
Possible reason for (3): We don't distincguish syntactically between by-name and by-value elsewhere.

@lihaoyi
Copy link
Contributor

lihaoyi commented Aug 29, 2025

If we allow delay(300): println("hello"), wouldn't we then have to allow println: "hello", and wouldn't println: "hello" be indistinguishable from a type ascription?

@GLI-RK0
Copy link

GLI-RK0 commented Aug 29, 2025

If we allow delay(300): println("hello"), wouldn't we then have to allow println: "hello", and wouldn't println: "hello" be indistinguishable from a type ascription?

Sorry I might be missing something, why would we have to allow println: "hello"? I was under the impression that : would only trigger an attempt to interpret the following rhs as a lambda when the parameter is typed as such? I assume that's what Martin meant by option 2?

@lihaoyi
Copy link
Contributor

lihaoyi commented Aug 29, 2025

Sure, println is not a higher order function, and delay(300): is. But do you know that information during parsing? Because this distinction between "this is a type ascription" and "this is a function taking a code block on the right" needs to happen super early even before typechecking happens.

If you don't like println, how about delay(300): "hello": is this a function call with a type ascription, or a function call taking two parameter lists?

@odersky
Copy link
Contributor Author

odersky commented Aug 29, 2025

@lihaoyi Yes, indeed. Allowing arbitrary expressions after: would conflict with type ascriptions. So I think we need to bury the idea.

@odersky
Copy link
Contributor Author

odersky commented Aug 29, 2025

I believe we have a problem with the new build. It does not pick up the scala-library changes in the bootstrapped build.
I see:

-- [E008] Not Found Error: tests/pos/closure-args.scala:1:29 -----------------------------------------------------------
1 |import language.experimental.relaxedLambdaSyntax
  |                             ^^^^^^^^^^^^^^^^^^^
  |                             value relaxedLambdaSyntax is not a member of object language.experimental

Yet, relaxedLambdaSyntax was added to language.experimental in the commit.

@@ -1,6 +1,6 @@
//> using options -rewrite -indent
//> nominally using scala 3.7.0-RC1
// does not reproduce under "vulpix" test rig, which enforces certain flag sets?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reproduction was a parser crash instead of (some) error (only under -rewrite).

I haven't looked yet, but I wonder if it is worth trying to preserve the migration help (in 2025 almost '26)

parentheses are required around the parameter of a lambda

They can use copilot.

@odersky odersky added the needs-sip A SIP needs to be raised to move this issue/PR along. label Sep 26, 2025
Previously, we need to indent after the error, e.g.
```scala
xs.map: x =>
  x + 1
```
We now also allow to write the lambda on a single line:
```scala
xs.map: x => x + 1
```
The lambda extends to the end of the line.
@odersky odersky force-pushed the one-line-colon-lambda branch from 07611bf to 007c4de Compare October 28, 2025 12:45
@odersky odersky added stat:sip-in-progress and removed needs-sip A SIP needs to be raised to move this issue/PR along. labels Oct 28, 2025
@odersky odersky marked this pull request as ready for review October 28, 2025 12:47
@odersky odersky requested a review from a team as a code owner October 28, 2025 12:47
@odersky
Copy link
Contributor Author

odersky commented Oct 28, 2025

This was accepted as ready or implementation in the SIP meeting of Oct 24th, 2025.

@WojciechMazur
Copy link
Contributor

No new regressions found in the OpenCB when comparing against current main

@odersky odersky merged commit 2f97633 into scala:main Oct 30, 2025
51 checks passed
@odersky odersky deleted the one-line-colon-lambda branch October 30, 2025 22:17
@odersky odersky added the backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. label Oct 30, 2025
@WojciechMazur WojciechMazur added this to the 3.8.0 milestone Nov 12, 2025
WojciechMazur added a commit that referenced this pull request Nov 12, 2025
Backports #23821 to the 3.8.0-RC1.

PR submitted by the release tooling.
[skip ci]
@WojciechMazur WojciechMazur added backport:done This PR was successfully backported. and removed backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. labels Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:done This PR was successfully backported. stat:sip-in-progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants