pattern matching in JS
# 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
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: https://github.com/dscape/p/blob/master/pattern.js#L1 Nuno On Sat, Aug 11, 2012 at 8:29 PM, Nic Volanschi <nic.volanschi at free.fr>wrote: > 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]: > http://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. > > Regards, > Nic. > > [1] The custom notations library: > http://mypatterns.free.fr/js/stable/mypatterns/notations.js > [2] Try customized notations in JavaScript online: > http://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. > http://nic.volanschi.free.fr/papers/notations-scp12.pdf > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120811/d32aace0/attachment-0001.html>
On Wed Jul 4 08:01:43 PDT 2012 Brendan Eich brendan at mozilla.org wrote:
On Mon Jul 9 09:19:54 PDT 2012 Russell Leggett russell.leggett at gmail.com wrote:
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:
Nevertheless, I think that this (modest) prototype could serve discussions about future patterns in JS in the following ways:
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).
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