N.B.: This is an experiment. It is under development. Do not use in production. Contributors are welcome!
jspm allows to use the expressivenes and power of pattern matching using Javascript. Just plain Javascript; no macros or other syntactic sugar constructs.
Pattern matching is used to recognise the form of a given value and let the computation be guided accordingly, associating with each pattern an expression to compute.
- Pattern matching on atoms (object literals, numbers, booleans null, undefined - no strings because regexp does the job)
- Pattern matching on arrays (like lists)
- Pattern matching on ADTs (Algebraic Data Types)
- Definition of variants
- Exhaustiveness and redundancy checking
- Usage of bindings, parameters and wild cards
Factorial definition
var fact = $p.fun({
'0' : function () { return 1 },
'__n__': function (n) { return n * fact(n - 1) }
});
Application
fact(3);
<< 6
Supported patterns:
- Head, tail constructor:
x::xs
orx1::x2::xs
- Array literal:
[]
or[4, 3, 1, 7]
var sum = $p.fun({
'[]': function () { return 0 },
'x::xs': function () { return x + sum(xs) }
});
sum([1, 4, 3]);
<< 8
Variants are special types of ADTs that allow to define data types (variants) with constructors that are formed by other types.
$p.variant('list', true).make({
'Empty': null,
'Cons': [$p.Any, list]
});
var myList = Cons(1, Cons(2, Cons(3, Empty(null)))); // Creates a list of 3 elements
var sum = $p.fun({
'list:Empty' : function () { return 0 },
'list:Cons' : function (head, tail) { return head + sum(tail) }
});
Bindings are a useful way to pass more information to the function matching the pattern. Below usage example:
var add = $p.fun({
'0' : function () { return this.val },
'__n__' : function (n) { return n + this.val }
});
add(4, {'val': 3});
<< 7
Parameters allow to bind values to variable names in the matching function.
Usage of parameters -
Wildcards (_) are useful for grouping everything that is not being matched by the other patterns. Usage example (not so useful example...):
var hello = $p.fun({
'0': function () { return 'Ooopss..' },
'_': function () { return 'Hello World!' }
})
hello(0);
<< 'Ooopss...'
hello(347);
<< 'Hello World!'
In pattern matching we must ensure exhaustiveness (all patterns are covered) and that there are no redundancies (repeating same patterns).
In the next release jspm will support guards as well as more syntactic sugar for both pattern matching and sum type definition.