3

Simple pattern matching for ES6

 2 years ago
source link: https://rreverser.com/gh-xmatch/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

View on GitHub

Simple pattern matching for ES6 (no transpilation!)

Property matching

const { match } = require('xmatch');

match(obj, [
	({ x }) => console.log('x', x),
	({ y }) => console.log('y', y),
	({ z }) => console.log('z', z),
	// Exhaustive match; will throw `xmatch.UnmatchedPatternError` unless uncommented:
	// other => console.error('Something else', other),
]);

Iterable matching

const { match } = require('xmatch');

match(arr, [
	([]) => 'empty',
	([x]) => `x=${x}`,
	([x, y]) => `x=${x},y=${y}`,
	([x, y, ...{ length }]) => `x=${x},y=${y},rest.length=${length}`,
]);

Custom guards

const { match, guard } = require('xmatch');

match(obj, [
	({ command }) => {
		// When you want to match simple values:
		guard(command === 'ignore');
		/* Do nothing */
	},
	({ command }) => {
		// Or, say, match result of regex:
		let [, name, args] = guard(command.match(/^(\w+):(.*)$/));
		console.log({ name, args });
	},
	({ command }) => {
		throw new Error(`Invalid command: ${command}`);
	},
]);

Shape assertions

const { guard } = require('xmatch');

const { x, y } = guard({ x: 1, y: 2 }); // OK
const { x, y } = guard({ x: 1, z: 2 }); // throws `xmatch.UnmatchedPatternError`

Known issues

  • You can't use literals directly in patterns (this is limitation of ES6 syntax, can be fixed as part of https://github.com/tc39/proposal-pattern-matching).
  • You can't use default values for parameters. This is limitation of the way matching is implemented, and you'll have to resolve defaults yourself if that's what you want.
  • Trying to further destructure or access undefined properties of an object will also trigger the match guard (#1). This is tricky to workaround without changing the syntax, but I'll look into it (and happy to hear any suggestions).
  • This uses dynamic metaprogramming via Proxy which might have undesirable performance effect on hot code paths. If your benchmarks suggest it's causing critical performance issues, consider using transpiler plugins instead.
  • Proxy is not implemented in pre-ES6 browsers and can't be polyfilled, so use this only if you're okay with the supported target set: https://caniuse.com/#feat=proxy

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK