Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 7, 2025

Summary

This PR addresses issue #45697 by clarifying the spacing conventions for pattern matching in the F# style guide. The changes emphasize consistency between expression and pattern formatting, specifically addressing whether to use Some(a, b) or Some (a, b) in patterns.

Problem

The issue raised a question about spacing before parentheses in pattern matching:

match x with
// with a space
| Foo (a, b) -> ()
// without a space
| Bar(c,d,e) -> ()

As discussed by @dsyme and @BillWagner, F# style should value consistency between expressions and patterns, and the default formatting (used by Fantomas) does not add spaces before parentheses for uppercase identifiers.

Changes

1. Expression-Pattern Consistency (line ~248)

Added clarification after the application expressions section to establish the principle that pattern formatting should match expression formatting:

// ✔️ OK - Consistent formatting for expressions and patterns
let result = Some(value)

match result with
| Some(x) -> x
| None -> 0

2. Pattern Matching Spacing Guidelines (line ~1166)

Added comprehensive guidance in the pattern matching section with clear examples:

No space before parentheses in pattern arguments:

// ✔️ OK
match x with
| Some(y) -> y
| None -> 0

// ❌ Not OK, pattern formatting should match expression formatting
match x with
| Some (y) -> y
| None -> 0

Spaces between curried arguments:

// ✔️ OK - space between curried arguments
match x with
| Pattern arg (a, b) -> processValues arg a b

// ❌ Not OK - missing space between curried arguments
match x with
| Pattern arg(a, b) -> processValues arg a b

Impact

  • Clarifies long-standing formatting question for F# developers
  • Aligns documentation with Fantomas formatter default behavior
  • Emphasizes the F# community's value on consistency between expressions and patterns
  • No breaking changes, only documentation clarification

Fixes #45697

Co-authored-by: BillWagner [email protected]

Original prompt

This section details on the original issue you should resolve

<issue_title>F# style guide question - Space before parenthesis in pattern in F# code</issue_title>
<issue_description>Hello @dsyme,

Should there be a space after a pattern (SynPat.LongIdent if you will) that has a parenthesis argument.

match x with
// with a space
| Foo (a, b) -> ()
// without a space
| Bar(c,d,e) -> ()

//cc @auduchinok


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Comments on the Issue (you are @copilot in this section)

@dsyme > Should there be a space after a pattern (SynPat.LongIdent if you will) that has a parenthesis argument.

I believe we have to prefer consistency and have the default settings should be identical to expressions, so if expressions are set to format like this:

SomeUpperCaseFunction(a, b)   // expression
SomeType(a, b)   // expression
Some(a, b)   // expression
SomeCurriedThing arg (a, b)   // expression

then patterns format similarly:

| Some(a, b) ->  // pattern
| SomeActivePattern arg (a, b) ->  // active pattern with parameter

The value of consistency seems just too high to do much else.

That said I personally prefer expression formatting where single identifier upper case identifiers get spaces just like lower case, e.g.

SomeType.Method(a,b) // two identifiers in dot notation, uppercase last = method

Some (a, b)   // expression

| Some (a, b) ->  // pattern

But that would be up to me to advocate such a separate rule for expressions - and again for patterns the key thing is consistency I think.

As an aside I also remove parentheses for single atomic arguments, e.g. as follows, though that's somewhat orthogonal and Fantomas currently preserves whatever is in the source code:

SomeType "abc"
SomeType.Method "abc"
someObject.Method "abc"

Some "abc"   // expression

| Some "abc" ->  // pattern
@dsyme > From a Fantomas point of view, it feels like we can re-use the settings fsharp_space_before_uppercase_invocation and fsharp_space_before_lowercase_invocation to determine if there should be a space or not.

Yes, you should reuse whatever settings are used for expression formatting.

This was suggested in the past before (at Fantomas side) but again might not cover all cases.

Agreed it doesn't cover that case (and not proposing that we should)</comment_new>
<comment_new>@BillWagner
As noted, the F# style should not recommend different styles for patterns and expressions. This article should clearly state that the recommended F# style places a high value on consistency (per @dsyme 's comments). Therefore, the additional spaces aren't recommended.</comment_new>

Fixes #26465

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.


Internal previews

📄 File 🔗 Preview link
docs/fsharp/style-guide/formatting.md F# code formatting guidelines

@dotnet-policy-service dotnet-policy-service bot added the okr-quality Content-quality KR: Concerns article defects (bugs), freshness, or build warnings. label Oct 7, 2025
@Copilot Copilot AI changed the title [WIP] F# style guide question - Space before parenthesis in pattern in F# code Clarify F# pattern matching spacing to align with expression formatting Oct 7, 2025
@Copilot Copilot AI requested a review from BillWagner October 7, 2025 13:53
Copilot finished work on behalf of BillWagner October 7, 2025 13:53
Copy link
Member

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

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

With one suggestion, this is ready for final review.

@BillWagner BillWagner marked this pull request as ready for review October 8, 2025 13:06
@Copilot Copilot AI review requested due to automatic review settings October 8, 2025 13:06
@BillWagner BillWagner requested review from a team as code owners October 8, 2025 13:06
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR clarifies the F# style guide's position on spacing conventions for pattern matching to emphasize consistency between expression and pattern formatting. The main issue addressed was whether to use Some(a, b) or Some (a, b) in patterns, with the guide now clearly recommending no space before parentheses to match expression formatting.

  • Added principle that pattern formatting should match expression formatting for consistency
  • Provided comprehensive examples showing correct and incorrect spacing in pattern matching
  • Clarified spacing rules for both simple patterns and curried arguments in patterns

@T-Gro T-Gro merged commit 636adf1 into main Oct 14, 2025
10 checks passed
@T-Gro T-Gro deleted the copilot/fix-380ee437-4e0e-4e37-a706-c6b4f2d3d7d5 branch October 14, 2025 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dotnet-fsharp/svc okr-quality Content-quality KR: Concerns article defects (bugs), freshness, or build warnings.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

F# style guide question - Space before parenthesis in pattern in F# code

3 participants