[racket] rho-contracts.js: Racket-style contracts for plain JavaScript

From: Sean McBeth (sean.mcbeth at gmail.com)
Date: Mon May 20 19:16:10 EDT 2013

That is really cool!


On Mon, May 20, 2013 at 6:08 PM, Guillaume Marceau <gmarceau at gmail.com>wrote:

> Hi all,
>
>
> In case this might interest some folks here. I now work for a start up in
> New York. We're doing physics-based analysis of green buildings. I just
> received permission to release our JavaScript implementation of Racket's
> contracts under an open source license, MPL to be precise.
>
> https://github.com/sefaira/rho-contracts.js
>
>
> After some fiddling, I was able to create a syntax that's readable enough
> (I hope). Here is the `derive` function wrapped in a contract:
>
> var c = require('contract')
>
> // define the contract that's used below (since it's used twice):
> c.numberToNumber = c.fun( { x: c.number } ).returns(c.number)
>
> // derive: returns a function that is the numerically-computed derivative
> //         of the given function.
> var derive =
>   /* This is the specification: */
>   c.fun( { fn:     c.numberToNumber },
>          { deltaX: c.number         } )
>    .returns(c.numberToNumber)
>    .wrap(
>          /* And the implementation goes here: */
>          function(fn, deltaX) {
>            return function(x) {
>             return (fn(x+deltaX/2) - fn(x-deltaX/2))/deltaX
>            }
>          })
>
>
> Once the contract is in place, you get the kind of error message you
> always wanted to have in JavaScript, but never could, such as the basic
> "wrong number of arguments.", and you also get contract error with blame
> (though only function-level blame, not between-module blame):
>
>   // Error: forgetting an argument:
>   > derive(quadratic)
>   ContractError: Wrong number of arguments, expected 2 but got 1
>
>   // Error: calling with the arguments flipped:
>   > derive(1.0, quadratic)
>   ContractError: Expected fun, but got 1
>   For the `fn` argument of the call.
>
>   // Error: calling with the wrong kind of function:
>   > var d = derive(function(x) { return "**" + x + "**" }, 1.0)
>
>   // The contract-checking shell is now installed around `fn` inside of
> `d`;
>   // throws an error when called:
>   > d(100)
>   ContractError: `fn()` broke its contract
>   Expected number, but got '**100.5**'
>   for the return value of the call.
>
>
>
> There is also support for placing contract on whole module at a time.
> Notably, the contract library itself is wrapped with contracts, as it
> should:
>
> https://github.com/sefaira/rho-contracts.js/blob/master/contract.face.js
>
>
> This has been in production at sefaira.com for about a year now. We're
> really happy to have a piece of Racket-lore be our first open source
> release. Hopefully there will be more.
>
>
> Best,
>
> Guillaume
>
>
>
>
>
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130520/23d56d5d/attachment.html>

Posted on the users mailing list.