Stage: 0
Author: Kat Marchán (npm, @maybekatz)
Champions: Brian Terlson (Microsoft, @bterlson), Sebastian Markbåge (Facebook, @sebmarkbage), Kat Marchán (npm, @maybekatz)
This proposal adds a pattern matching expression to the language, based on the existing Destructuring Binding Patterns.
It's structured into multiple parts:
-
The core proposal for the
match
API, which is based directly on destructuring binding patterns. -
A proposal extending both
match
and regular destructuring withas
patterns, so patterns can both be matched and be assigned to identifiers. -
A proposal to add tagged collection literals, both as construction literals, and as their corresponding destructuring patterns.
-
A document including suggestions for other future proposals, which are dependent on
match
, but do not directly affect the main behavior of the feature.
This proposal draws heavily from corresponding features in Rust, F#, Scala, and Elixir.
Matching fetch()
responses:
const res = await fetch(jsonService)
match (res) {
when {status: 200, headers: Headers~{'content-length': s}} ~> `size is ${s}`
when {status: 404} ~> 'JSON not found'
when {status} if (status >= 400) ~> throw new RequestError(res)
}
Terser, more functional handling of Redux reducers. Compare with this same example in the Redux documentation:
function todoApp (state = initialState, action) {
match (action) {
when {type: 'set-visibility-filter', filter: visFilter} ~>
return {...state, visFilter}
when {type: 'add-todo', text} ~>
return {...state, todos: [...state.todos, {text}]}
when {type: 'toggle-todo', index} ~> {
return {
...state,
todos: state.todos.map((todo, idx) => idx === index
? {...todo, done: !todo.done}
: todo
)
}
}
when {} ~> {} // ignore unknown actions
}
}
Or mixed in with JSX code for quick props handling:
<Fetch url={API_URL}>{
props => {
match (props) {
when {loading} ~> return <Loading />
when {error} ~> return <Error error={error} />
when {data} ~> return <Page data={data} />
}
}
}
</Fetch>
(via Divjot Singh)
General structural duck-typing on an API for vector-likes:
const getLength = vector => {
match (vector) {
when { x, y, z } ~> return Math.sqrt(x ** 2 + y ** 2 + z ** 2)
when { x, y } ~> return Math.sqrt(x ** 2 + y ** 2)
when [...etc] ~> return vector.length
}
}
getLength({x: 1, y: 2, z: 3}) // 3.74165
- Babel Plugin
- Sweet.js macro (NOTE: this isn't based on the proposal, this proposal is partially based on it!)