intro.js | |
|---|---|
| Contracts.js is a JavaScript library that allows you to express and enforce complex run-time assertions on JavaScript code. You can write contracts for just about anything in JavaScript including functions (both first-order, higher-order, and dependent), objects, and arrays. | |
| To get an idea of how it works, consider this increment function
which simply adds | var inc = function(x) { return x + 1; }; |
| Calling | inc(4); // ==> 5 |
| For example if we call it with a string type coercion gives
us | inc("hello"); // ==> "hello1" |
| So let's see how contracts can help us. | |
| The contracts library provides three important functions here:
So this call to | inc = guard(
fun(Num, Num), // a function contract
function(x) { return x + 1; }); // the function to guard |
| When we call the guarded function with a number everything works just like normal. | inc(4); // ==> 5 |
| But when we call it with a string, the contract fails and we get a nice error message informing us of our mistake:
This lets us know which contract failed ( | inc("hello"); // fails contract! |
| We can also apply contracts to higher-order functions. | var hoFun = guard(
fun(fun(Num, Bool), Num),
function(f) {
if( f(42) ) {
return 42;
} else {
return -1;
}
}); |
| If the client client passes a function that doesn't pass its
contract, we will fail pointing blame on the client of | hoFun(function(n) { return "foo"; }); |
| There is also a combinator for objects. | guard(
object({ a: Str, b: Num}),
{ a: "foo", b: 42 }); |
| Along with arrays. Here the first two elements of
the array must be a | guard(
arr([Str, Num, ___(Bool)]),
["foo", 42, false, true, true, false, true]); |
| You can also write your own flat contracts using
the | var Even = check(function(val) {
return (val % 2) === 0;
}, "Even"); |
| The | var Num = check(function(val) {
return typeof(val) === "number";
}, "Number"); |
| You can also express dependent function contracts (where the result of calling a function depends on its arguments). | guard(
fun(Num, function(argument) {
return check(function(result) {
return result > argument;
});
}),
function(n) { return n + 1; });
|