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: Option
s, tuples and Seq
s. 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 withget
andisEmpty
is valid. - Instead of tuples, anything with
_1
through_N
is valid. - Instead of
Seq
, anything withlength
,apply
,drop
andtoSeq
is 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 Option
s 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.