Hi Scala Community!
This thread is the SIP Committee’s request for comments on a proposal to officialize and generalize name-based pattern matching. You can find all the details here.
Summary
In Scala, pattern matching is based on the notion of extractors: objects with an unapply or unapplySeq method that satisfies certain conditions. In Scala 2, extractors are mostly type-based, in the sense that their signature must conform to certain built-in types: Options, tuples and Seqs. Roughly, the possibilities can be summarized as:
-
def unapply(x: T): Boolean: extractor for 0 inner value -
def unapply(x: T): Option[U]: extractor for 1 inner value -
def unapply(x: T): Option[(U1, ..., UN)]: extractor for exactly N inner values -
def unapplySeq(x: T): Option[Seq[U]]: extractor for a variable number of values
Subtypes such as Some[U] also work, but for the most part specific built-in types are required. Since Scala 2.11, in a PR, which to this day remains the only real documentation of the feature, a certain form of name-based pattern matching has been supported.
In this proposal, we officialize name-based pattern matching, and in fact use it to entirely supersede the old type-based pattern matching:
- Instead of
Option, anything withgetandisEmptyis valid. - Instead of tuples, anything with
_1through_Nis valid. - Instead of
Seq, anything withlength,apply,dropandtoSeqis valid.
Read the documentation linked above for the exact details.
Currently, the implemented feature still has a type-based dependency on Product, but those should also be merged with the name-based system.
Implications
Name-based pattern matching offers the potential to define, when it matters, zero-cost extractors that avoid any allocation, unlike Options of tuples, which can incur several allocations.
The new rules are a superset of the rules of Scala 2, so they will allow all existing extractors to keep working.
Opening this Proposal for discussion by the community to get a wider perspective and use cases.