An extension for non class pattern name

A pattern currently has the form:

A(p1,..,pN) = e

and is transformed in:

(p1,..,pN) = A.unapply(e)

The pattern name (A) has to be a class (or object) name and the pattern definition is located in class A unapply method.

The proposition is to generalise this to the case where the symbol A is not a class or object name (I now call it “a”), in which case

a(p1,…,pN) = e
is transformed in:
(p1,..,pN) = e.a

The pattern definition is then found in the class of e.

A classical use of this is to be able to see complex numbers as a couple of (x,y) coordinates or (rho,theta) polar coordinates.

class Complex(val x,y:Double) {
  ...
  def polar = (...,...) //polar coordinates of this
  def polar(r:Double,t:Double) = Complex(...,...) //not mandatory
}
val polar(r,t) = Complex(0,-1) //use Complex.polar. r=1, t=-pi/2
val c = Complex.polar(r,t) //use Complex.polar(r,t). c = Complex(0,-1)

This feature is really of interest in the case of nested patterns.
The intention is to allow different “views” of a class, and to consider the responsability of the class to show itself in different ways.

You can already achieve your desired API by defining

object polar {
  def unapply(c: Complex): Some[(Double, Double)] = Some(c.polar)
}
object cartesian {
  def unapply(c: Complex): Some[(Double, Double)] = Some((c.x, c.y))
}

There is no need to to add a language feature for this.

4 Likes