fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

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

Open adamyakes opened this issue 5 months ago • 0 comments

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.

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.

// 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

adamyakes avatar Aug 28 '25 14:08 adamyakes