pattern matching in JS

# Nic Volanschi (13 years ago)

On Wed Jul 4 08:01:43 PDT 2012 Brendan Eich brendan at mozilla.org wrote:

If only JS had pattern matching! [...]

On Mon Jul 9 09:19:54 PDT 2012 Russell Leggett russell.leggett at gmail.com wrote:

I know that full blown patterns are out of scope (though I'm hoping maybe this discussion might change that), but even if we can't have it now, I think irrefutable destructuring would really make people see the potential.

Actually, pattern matching can be implemented in the current JS language, as a very simple library [1] of 150 lines of JS (plus more 150 lines of optimizations). The library can be tested online in any browser with no extra installation, at the following address [2]: mypatterns.free.fr/js/stable/mypatterns/notations.html The implementation and the matching concepts are completely described in a recent paper [3].

Of course, this library-based implementation is inferior to the kind of language support being discussed for Harmony, as it implies some notational overheads. For instance, when in Harmony (as currently foreseen) you would write:

let [x...l] = [1,2,3];

to bind x=1 and l=[2,3], using the library you would have to call a "match" function like this:

let s = match([1,2,3], "[%x|%l]");

which binds s={x:1,l:[2,3]}. (As you may see, in the current implementation, "|" is used instead of "..." and variables in the pattern are prefixed by "%", but these can be changed easily - the notation language can in fact be customized arbitrarily.)

Thus, the notational overheads (apart the above accidental diffs) are:

  • putting quotes around the pattern to make it a string,
  • explicitly calling the match function and storing its results in s, and
  • getting x and l rather as s.x and s.l

Nevertheless, I think that this (modest) prototype could serve discussions about future patterns in JS in the following ways:

  1. by offering a playground for different pattern dialects in today's JS, which can be better than discussing them only on paper examples, until fully implemented in the language. Indeed, by studying the straightforward implementation [1], one can see that every notation (e.g. the arrays notation) can be changed by simply modifying one single function (Array.prototype.matches() in this case).

  2. by introducing (in [3]) a simple conceptual framework in which the meaning of a pattern can be cleanly defined. Moreover, this meaning applies to all of: destructuring patterns, binding patterns and refutable patterns. This is a bit similar to the (elegant!) factorized definition of refutable and irrefutable patterns in the strawman:pattern_matching, but additionnally separates the definitions of array patterns, object patterns, and patterns for different kinds of literals, instead of defining the meaning of all of them in a single recursive function.

I am of course available for further details for anyone finding this topics useful.

, Nic.

[1] The custom notations library: mypatterns.free.fr/js/stable/mypatterns/notations.js [2] Try customized notations in JavaScript online: mypatterns.free.fr/js/stable/mypatterns/notations.html [3] Pattern Matching for the Masses using Custom Notations. Science of Computer Programming 77:5 (2012) 609–635. nic.volanschi.free.fr/papers/notations-scp12.pdf

# Nuno Job (13 years ago)

I did this (which is pure valid js):

var map = require('p')() , _, f, ac ;

map(f, [], ac, function (_, _, ac) { return console.log(ac); }); map(f, _, ac, function (f, l, ac) { ac.push(f(l.shift())); map(f, l, ac); // l is now tail });

map(function plusone(x) { return x+1; }, [1,2,3], []);

But yeah, limitations are obvious. Still its pretty fun!

Code at: dscape/p/blob/master/pattern.js#L1

Nuno