dotnet / dotnet/fsharp

Single line list with `if` doesn't obey published operator precedence with `;`

Open
#18,870 0 comments 0 reactions 0 assignees View on GitHub
Area-Compiler-Syntax Feature Improvement
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

In the discussion of https://github.com/fsharp/fslang-suggestions/issues/1438, I think that the way one-line lists are being parsed is not consistent with operator precedence. (`;` is lower precedence than `if`)

**Repro steps, Expected Behavior vs. Actual Behavior**

I was trying to recreate this as a one-liner.

```fsharp
let x = false
[ 1
2
if x then
3
4
]
val it: int list = [1; 2; 4]
```

But if `;` is lower precedence than `if`, these examples seem incorrect to me. I essentially expect all of them to parse as the above code.

```fsharp
// Drops everything after the if
[1; 2; if x then 3; 4]
val it: int list = [1; 2]
// Expected to parse as
[(1); (2); (if x then 3); (4)]

// Seems to work
[1; 2; if x then 3 else (); 4]
val it: int list = [1; 2; 4]
// But not when x is true
val it: int list = [1; 2; 3]

// Still doesn't work
[1; 2; if x then begin 3 end; 4;]
val it: int list = [1; 2]
// Actually does seem to work when x is true
val it: int list [1; 2; 3; 4]
```
The linked issue has block that can be run directly.

**Known workarounds**

- Don't write a one-line `if`
- Use `option` followed by `Seq.choose id`
- Use nested lists with `yield!`

**Environment**

* Windows 11
* .NET 8
* Visual Studio, Visual Studio Code, F# interactive

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.