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

Implement multi-pattern matching in match expressions #5449

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

OceanOak
Copy link
Collaborator

@OceanOak OceanOak commented Jan 30, 2025

Changelog:

Area of change
- add support for multi-pattern matching in match expressions

@OceanOak
Copy link
Collaborator Author

OceanOak commented Feb 4, 2025

These tests fail in F# but are currently passing in Darklang

  // All patterns should have the same variables.
  (match (1L,2L) with
   | (x,2L) | (2L,y) when x == y -> "pass"
   | _ -> "fail") = "pass"

  // The two sides bind different sets of variables
  (match (1L,2L) with
    | (x,y) | (x,_) when y > 0L -> "pass"
    | _ -> "fail") = "pass"

  // incompatible pattern structures: List vs Cons
  (match [1L;2L] with
   | [x;y] | x::y -> "pass"  // List vs Cons pattern
   | _ -> "fail") = "pass"
   
  // mixing different types
  (match (1L, "test") with
   | (x, "test") | ("test", x) -> x
   | _ -> "fail") = 1L

Unrelated to pattern grouping :

 // the type should match. can't match an int with a string
  (match (1L, "test") with
    | ("test", x) -> x
    | (x, "test") -> x
    | _ -> "fail") = "fail

//  all branches of a pattern match expression must return values of the same type
 (match (1L,2L) with
    | (x,2L) | (2L,x) when x = 1L -> "pass"
    | _ -> 0L) = "pass"

Do we want to be as strict?

@StachuDotNet
Copy link
Member

StachuDotNet commented Feb 4, 2025

These tests fail in F# but are currently passing in Darklang

  // All patterns should have the same variables.
  (match (1L,2L) with
   | (x,2L) | (2L,y) when x == y -> "pass"
   | _ -> "fail") = "pass"

This should fail, since we're referencing a y where one doesn't exist.
(misc.: worth changing the fail branch to "fail")

  // The two sides bind different sets of variables
  (match (1L,2L) with
    | (x,y) | (x,_) when y > 0L -> "pass"
    | _ -> "fail") = "pass"

I think this is OK for now -- should fail later when we have at-rest checks.
(misc.: worth changing the fail branch to "fail")

  // incompatible pattern structures: List vs Cons
  (match [1L;2L] with
   | [x;y] | x::y -> "pass"  // List vs Cons pattern
   | _ -> "fail") = "pass"

(misc.: worth changing the fail branch to "fail")

// mixing different types
(match (1L, "test") with
| (x, "test") | ("test", x) -> x
| _ -> "fail") = 1L

OK

Unrelated to pattern grouping :

 // the type should match. can't match an int with a string
  (match (1L, "test") with
    | ("test", x) -> x
    | (x, "test") -> x
    | _ -> "fail") = "fail

OK

//  all branches of a pattern match expression must return values of the same type
 (match (1L,2L) with
    | (x,2L) | (2L,x) when x = 1L -> "pass"
    | _ -> 0L) = "pass"

Do we want to be as strict?

I'd say this is OK - these are things we can complain about during at-rest analysis once we have that

@OceanOak OceanOak marked this pull request as ready for review February 5, 2025 16:29
@OceanOak OceanOak requested a review from StachuDotNet February 5, 2025 16:29
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