jashkenas/coffee-script — Issue #1833: Possibly add simplified contracts
Author: disnet
Created: 2011-11-07 23:20:51+00:00
State: open

So a full contract system like [contracts.coffee](https://github.com/disnet/contracts.coffee) due to its dependence on Proxies and a runtime library can't be added CoffeeScript proper. However, I think there's a way to add simplified contracts that doesn't require proxies or a library by adding straightforward pre and post assertions.

For example

square :: (Num) -> Pos
square = (x) -> x * x

Becomes something like

var square;
square = function(x) {
var res;
if (typeof(x) !== 'number') { throw "failed contract"; }
res = x * x;
if (res < 0) { throw "failed contract"; }
return res;
}

Probably could even do higher-order stuff by wrapping function arguments

sort :: (Array, (Num) -> Bool) -> Array
sort = (arr, cmp) -> ... cmp y ...

Becomes

var sort;
sort = function(arr, cmp) {
var checked_cmp;
checked_cmp = function(x) {
var res;
if (typeof(x) !== 'number') { throw "violation"; }
res = cmp(x);
if(typeof(res) !== 'boolean') { throw "violation"; }
return res;
}
... checked_cmp(y) ...
}

Without a runtime it probably won't be able to transparently do full object contracts (guarding property write), object invariants, or correct blame (requires modules, even if pseudo-faked as in contracts.coffee).

But I think it would still be a useful/clean/expressive way of putting pre/postconditions in your code.

Do people think this is something useful and a good fit for CoffeeScript? If it has a chance of getting in I can work on a patch.