Skip to content

Add "pattern" scope type #2177

Open
Open
@wenkokke

Description

@wenkokke

I propose we add a scope type for the patterns in pattern matches, which are very important in functional languages like Haskell, Scala, and Rust, and increasingly important in languages such as JavaScript (see tc39) and Python (see pep 636).

// TypeScript
function fst<A, B>(tup: [A, B]) {
  const { x, y } = tup;
  //    ^^^^^^^^
  return x;
}
// Using tc39
function fst<A, B>(tup: [A, B]) {
  match (tup) {
    when ({ x, y }): return x;
    //    ^^^^^^^^
  }
}
# Python
def fst(tup):
  match tup:
    case (x, y): return x
#        ^^^^^^
// Scala
def fst[A, B](tup:  (A, B)): A =
  tup match {
    case (x, y) => x
    //   ^^^^^^
  }
-- Haskell
fst :: (a, b) -> a
fst (x, y) = x
--  ^^^^^^
// Rust
fn fst(tup: (A, B)) {
  match tup {
    (x, y) => x
//  ^^^^^^
  }
}

Patterns are different from conditions. The easiest way to show this is by implementing the if then else construct using patterns.

def ifThenElse(cond, ifTrue, ifFalse):
  match cond:
#       ^^^^  <-- "condition"
    case True:
#        ^^^^  <-- "pattern"
      return ifTrue()
    case False:
#        ^^^^^  <-- "pattern"
      return ifFalse()

Patterns are not adequately covered by branches, since "branch" selects the entire branch, which may match on multiple patterns.

and ::  Bool -> Bool -> Bool
and True True = True
--  ^^^^^^^^^^^^^^^^  <-- branch
--  ^^^^  <-- pattern
--       ^^^^  <-- pattern
and _    _    = False
--  ^^^^^^^^^^^^^^^^^ <-- branch
--  ^  <-- pattern
--       ^  <-- pattern

This makes it impossible to use "branch" to select, e.g., the first pattern in the second branch.

See related issues #579 and #1174.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions