Could it be possible to allow variable binging in patmat alternatives for Scala 3.x?

I wonder if new simplified pattern matching make it possible to allow variable bindings for pattern match alternatives like Rust do?

For example, this would be allowed:

enum Pet:
  case Dog(name: String), Cat(name: String)
  case Ant(id: Long), Bee(id: Long)

def greet(pet: Pet): Unit = pet match
  case Dog(name) | Cat(name) => println(s"Who's the good boyo, $name?!")
  case Ant(number) | Bee(number) => println(s"Go back to your hive #$number, Sun's setting!")
  // Following two cases should be a compile time error due to name or type mismatching
  // case Dog(woofer) | Cat(meowster) => ???
  // case Dog(id) | Ant(id) => ???

Example set of rules could be something like that:
For all binding groups of patmat alternatives {n1_1: P1_1, n1_2: P1_2, .., n1_N1: P1_N1}, {n2_1: P2_1, n2_2: P2_2, .., n2_N2: P2_N2}, ... following should apply:

  1. N1 == N2 == ...;
  2. Set(n1_1, ..., n1_N1) == Set(n2_1, ..., n2_N2) == ...
  3. For every ni_k == nj_l it is true that Pi_k =:= Pj_l (maybe could be relaxed to Pi_k | Pj_l?).

I think it will be very useful even restricted to product or product-sequence patmats.

Or it there some unknown to me blocker for such functionality in Scala?

5 Likes

I hacked a prototype of this together during a “Scala spree” day, a couple of year ago. See the PR I did to my own fork here: [WIP] Variables in pattern alternatives by LPTK · Pull Request #1 · LPTK/dotty · GitHub

The goal was just to get it working, and the implementation is quite ugly. One of the difficulties I found is that Scala symbols are not meant to be bound in several places at the same time, making things quite awkward. Also, adapting all the pattern matching code in the successive stages of the compiler pipeline to support the new feature is not straightforward. My hack used mutation behind the scenes to implement this by cutting corners, which won’t be viable in a real implementation.

EDIT: the corresponding feature request: Support Variables in pattern alternatives · Issue #12 · lampepfl/dotty-feature-requests · GitHub

2 Likes