Skip to content

Instantly share code, notes, and snippets.

@dabbott
Last active January 20, 2017 17:12
Show Gist options
  • Save dabbott/f39458157e7d50a3428deb1a183ad247 to your computer and use it in GitHub Desktop.
Save dabbott/f39458157e7d50a3428deb1a183ad247 to your computer and use it in GitHub Desktop.
JavaScript Match Expression
// Match expression
//
// `match` behaves similarly to `switch`. `match` is an expression, while `switch` is
// a statement, but the main idea is the same. The value of the `match` expression is
// the completion value of the chosen case.
//
// Since we might not be able to use the name `match` due to how common it is in
// existing code (e.g. String.prototype.match), alternative ideas:
//
// switch* pattern match*
//
// However, you can use `async` as a variable name despite it being a keyword, so
// maybe this isn't a big deal, so long as the grammar isn't ambiguous.
//
// -----
// Example 1. Matching literals
//
// Here `match` can be seen as a convenient replacement for switch, when a completion
// value is needed.
const str = 'yes'
const simple = match (str) {
case 'yes': true
case 'no': false
default: null
}
console.log(simple) // => true
// Example 2. Destructured array matching
//
// The real power of match comes when we start destructuring arrays and objects.
// Here we merge two sorted arrays by destructuring the arrays.
const merge = (xs, ys) =>
match (xs, ys) {
case ([], ys): ys
case (xs, []): xs
case ([x, ...xs], [y, ...ys]):
if (x < y) [x, ...merge(xs, [y, ...ys])]
else [y, ...merge([x, ...xs], ys)]
}
console.log(merge([2], [1, 3])) // => [1, 2, 3]
// Example 3. Destructured object matching
//
// Here we check an object for several different cases. Note that we can check for
// the existence of a key, or for a specific value of a key. The syntax is the same
// as the left-hand-side of destructured assignment.
const obj = { first: 'Devin', last: 'Abbott', awesome: true }
const fullname = match (obj) {
case { first, last }: `${first} ${last}`
case { first }: `${first}`
case { awesome = true }: `No name needed, too awesome`
default: `Invalid name: 'first' field required`
}
console.log(fullname) // => "Devin Abbott"
// Other ideas
// match could be a function expression, e.g.
// const f = match (x, y) => { case (1, 2): 'ok' }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment