Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"as" pattern with an identifier picks a literal #18315

Open
IS4Code opened this issue Feb 13, 2025 · 4 comments
Open

"as" pattern with an identifier picks a literal #18315

IS4Code opened this issue Feb 13, 2025 · 4 comments
Labels
Area-Compiler-PatternMatching pattern compilation, active patterns, performance, codegen Bug Impact-Medium (Internal MS Team use only) Describes an issue with moderate impact on existing code. Needs-design
Milestone

Comments

@IS4Code
Copy link

IS4Code commented Feb 13, 2025

There has been a change in F# 6 that introduces arbitrary patterns to the right of as. However, this is also a breaking change in case an identifier is used that starts with an uppercase letter, which was an already valid syntax before F# 6 to create a new variable.

Repro steps

[<Literal>]
let Co = 2
match 1 with
| 1 as Co -> printf "1"
| _ -> printf "other"

Expected behavior

The match should succeed, bind 1 to a new variable Co, and print "1".

Actual behavior

"other" is printed, since it interprets the first pattern as 1 as 2.

Known workarounds

Not using identifiers after as that start on an uppercase letter.

Related information

I am not sure if this behaviour is by design or not, since the RFC that introduces it does not discuss this case. However, I believe it is not by design, since the feature is marked as not being a breaking change. If the breaking change stays in, warnings should be issued since the interpretation of the code differs.

Environment: https://sharplab.io/#v2:DYLgZgzgPg2gPAGQJYBcCmAnAhsAfAXQFgAoYNFAAgGEB7CgXgoCYSBbLFAYwAsKBGCgHdU3ElH4UsEanQC0uCgAcMSAHYowFAER8tYigH0K8pSvWatNFN0xagA=

Trying this in an older version of the compiler exhibits the expected behaviour.

@brianrourkeboll
Copy link
Contributor

  • not according to the specification.

Do you mean the F# 4.1 specification?

Arbitrary patterns on the right-hand side of as were intentionally added in F# 6:

@IS4Code
Copy link
Author

IS4Code commented Feb 13, 2025

@brianrourkeboll Oh, thank you for the reference, I suppose I got failed there by the official documentation, 4.1 specification, and discord. I really wish there was a way to find out about this stuff without stumbling upon it by coincidence.

Since the & behaviour has been confirmed to be valid since F# 6 (and I am certainly glad it is!), I will edit the issue to leave only the 1 as Co part in. I believe that part is an undocumented breaking change.

@IS4Code IS4Code changed the title "as" patterns have "&" semantics "as" pattern with an identifier picks a literal Feb 13, 2025
@brianrourkeboll
Copy link
Contributor

brianrourkeboll commented Feb 13, 2025

I really wish there was a way to find out about this stuff without stumbling upon it by coincidence.

Yeah, there is a community effort under way to try to make it easier to keep the spec up to date: https://github.com/fsharp/fslang-spec?tab=readme-ov-file#overview

This is an initiative to create a more complete and community-maintainable F# spec.

This will be no small task, but we believe it is worthwhile and we count on community contributions.

We foresee three phases:

  1. Convert the latest official spec to markdown and create the structure and tools to make it community-maintainable. This is done.
  2. Add the post-4.1 features as documented in the RFCs to the spec. Our goal: a complete F# 10 spec.
  3. Make spec update part of new feature development so that an up-to-date spec can be released with every new major compiler release.

Right now, I believe it is in phase 2.

I will edit the issue to leave only the 1 as Co part in. I believe that part is an undocumented breaking change.

Yes, I think you are right that this was a breaking change. Note however that the compiler would have already emitted a warning for any identifier three characters or longer (#17878) starting with an uppercase letter in this position, which probably greatly limited any effect this might have had. (Edit: well, maybe it would have; maybe not, if identifiers in that position didn't go through the regular pattern typechecking. Either way, I guess we would probably have seen more noise in the last three years if it was really a widespread problem.)

@T-Gro
Copy link
Member

T-Gro commented Feb 14, 2025

I think this RFC can be revised to reduce the scope of supported expressions on the righthand side of as.
In this specific instance, I think constant as anotherConstant could emit a new warning without introducing breaking changes.

The described problem would however still remain if Co were e.g. a union case, but that behavior was the intended one for FS-1105.

@abonie abonie added Impact-Medium (Internal MS Team use only) Describes an issue with moderate impact on existing code. Area-Compiler-PatternMatching pattern compilation, active patterns, performance, codegen Needs-design and removed Needs-Triage labels Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-PatternMatching pattern compilation, active patterns, performance, codegen Bug Impact-Medium (Internal MS Team use only) Describes an issue with moderate impact on existing code. Needs-design
Projects
Status: New
Development

No branches or pull requests

4 participants