Skip to content

Allow multi-line expression at infix operator boundary#35

Merged
liufengyun merged 12 commits into
mainfrom
infix-continuation
Jun 21, 2026
Merged

Allow multi-line expression at infix operator boundary#35
liufengyun merged 12 commits into
mainfrom
infix-continuation

Conversation

@liufengyun

@liufengyun liufengyun commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Allow multi-line expression at infix operator boundary

Note: Only open expressions are affected. Closed expressions are not affected, there is no question where they end.

Context

Semicolon omission in statement syntax leads to the problem of when an expression ends.
Languages like Go and JavaScript use heuristics to automatically insert ; at line ends.
When things are not clear, users may add ; explicitly.

Languages like Swift and Scala use heuristics to tell whether or not to continue a multi-line expression.

Jo's rule is closer to Swift: multi-line expressions only continue at infix operator boundaries. An operator is taken as infix if there is space to its lhs and no space to rhs.

What has changed

Previously, the following code is invalid:

val a = 
  "hello, " + name + ". Message received: " +
  message

The programmer has to use parentheses to wrap the expression as in Python.

With the current change, the code above is accepted. One condition:

  • The two lines must be separated by an infix operator

Alternative 1

The separating infix operator rule allows the following code:

gcd:
  a + b +
  3
  5

Arguably, no one will write the code above. They can indent 3 to make things clear:

gcd:
  a + b +
    3
  5

We could add the requirement that the continued line must be indented. However, the price to pay is that the following code patterns become invalid:

a > 3
|| b == 10
|| c > 20

Users have to write

a > 3
  || b == 10
  || c > 20

We reject the design on the following two considerations.

First, the purpose of the PR is to reduce frictions for LLMs and new comers from other languages. The restriction goes against the goal.

Second, while a syntactic restriction can be justified by it rejecting unreadable code, it is a much weaker argument than rejecting error-prone code.

Alternative 2

Do nothing. The two common use cases for multi-line expressions are

  • string concatenation
  • complex Boolean expressions

Arithmetic expressions spanning multiple lines is less common and it's debatable whether it's a good style or not.

For both the two cases above, the existing colon syntax can better handle them:

def join(args: ..StringLike): String = ...

join:
  "hell, " + name + ". New message:"
  message

def or(conds: ..Bool): Bool = ...

or:
  a > 3
  b == 10
  c > 20

The counter-argument is friendliness for LLMs and users from other languages.

Checklist

  • Added / updated tests under tests/pos/ or tests/warn/
  • Docs updated if the change affects user-visible behavior
  • All commits are signed off (why?)
How to sign off commits

Use git commit -s to add the Signed-off-by line automatically:

To add a sign-off to the last commit retroactively:

git commit --amend -s --no-edit

To add sign-off to the last 3 commits:

git rebase --signoff HEAD~3

Security impact

No

Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
@liufengyun liufengyun changed the title Allow indented expression continuation at infix operator boundary Allow multi-line expression at infix operator boundary Jun 19, 2026
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
Signed-off-by: Fengyun Liu <fengyun.liu.cs@gmail.com>
@liufengyun liufengyun merged commit 2f38ec2 into main Jun 21, 2026
3 checks passed
@liufengyun liufengyun deleted the infix-continuation branch June 21, 2026 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants