Pattern Matching — Twice as robust in half the code
Who should read this article?
People who are curious about Functional Programming, Declarative Programming, or want to supercharge their code! 🚀
At the end, there’s a special syntax for Javascript & Typescript that you may not be aware of (hint: I wrote a pattern-matching library @matchbook/ts
)
What Pattern Matching is
First, the definition from Wikipedia:
In computer science, pattern matching is the act of checking a given sequence of tokens for the presence of the constituents of some pattern. In contrast to pattern recognition, the match usually has to be exact: “either it will or will not be a match.”
— Wikipedia
Practically speaking, you can replace “a given sequence of tokens” with “a given piece of data,” and “some pattern” with “some particular quality or state,” giving us:
In computer science, pattern matching is the act of checking a given piece of data for the presence of […] some particular quality or state.
At risk of being reductive, here’s what this boils down to most of the time in practice:
“Pattern matching is a construct that lets you handle Polymorphic data in a Declarative way.”
Let’s first cover what I mean by “Polymorphic data” and “Declarative”
Recap: Polymorphic Data
Sometimes in Programming, we want to solve a problem for multiple types of data at once, so that our code follows the Robustness principle, and is useful in as many contexts as possible.
Data that may be in one of several states, or shapes, is referred to as Polymorphic. (poly — many, morph — shape)
A common example is Shapes; a Triangle
, Square
, and Circle
are all shapes with a calculable area, so a function like function getArea(shape: Shape): number;
would be more robust than a getArea
function for each subtype.
That’s not to say a function getArea(c: Circle): number;
would not be valuable — just less robust.
Recap: Declarative code
In computer science, declarative programming is a programming paradigm […] that expresses the logic of a computation without describing its control flow.
Code that is Declarative describes the work to be done, and leaves how up to the individual parts.
Contrast this against Imperative Programming, which reads like a step-by-step recipe for the computer to follow.
You may have heard something to the effect of “Declarative Programming means Functional Programming” and “Imperative Programming means Object-Oriented.”
This is an observation, not a rule. You can absolutely write C# code that is very declarative, just as you can write imperative code in Haskell.
The problem Pattern Matching solves
Pattern matching is the Declarative counterpart to if
, else
, and switch
statements.
It allows you to handle conditions and polymorphism, without having to tell the computer how to tell when the conditions are met.
Pattern Matching by example
Case Studies
Let’s explore some concrete examples in a few languages — in each example we declare a Coin
type that can be a Penny
, Nickel
, Dime
, or Quarter
.
We also declare a function that accepts a Coin
and returns its value in dollars, represented by a floating-point number.
Rust
F#
C#
Typescript — switch
Typescript — @matchbook/ts
@matchbook/ts — Robust Pattern Matching in Javascript & Typescript
You may have noticed I snuck something in the last example that is not a language feature, but a library called @matchbook/ts
@matchbook/ts
is a Pattern Matching library I wrote that I encourage you to try out, if you’re curious about Pattern Matching and are working in a Javascript or Typescript project 😄
For the trivial example above, it’s actually more verbose than a switch case (although the syntax is much less obtuse IMO) but real code tends not to fit neatly into switch/case
statements.
@matchbook/ts
is capable of matching on data in way more ways than a switch/case; namely:
- Based on value
match(10, ...)
- Based on partial structure
match({name: 'Bob'}, ...)
- Based on predicate (type predicates, too!)
match(isDog, ...)
(isDog
is a function of typeIsDog :: Animal -> bool
) - Based on constructor
match(Dog, ...)
(Dog
is aclass
)
Check it out, let me know what you think!
Afterword
This is my first Medium article, so I invite any & all feedback in the comments — I don’t think this will be the last!