<div dir="ltr">That is really cool!<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, May 20, 2013 at 6:08 PM, Guillaume Marceau <span dir="ltr"><<a href="mailto:gmarceau@gmail.com" target="_blank">gmarceau@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi all, <div><br></div><div><br></div><div>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.</div>
<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><a href="https://github.com/sefaira/rho-contracts.js" target="_blank">https://github.com/sefaira/rho-contracts.js</a></div></blockquote><div>
<br></div>
<div>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:<br><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">
<div><font face="courier new, monospace">var c = require('contract')</font></div><div><font face="courier new, monospace"><br></font></div><div><font color="#990000" face="courier new, monospace">// define the contract that's used below (since it's used twice):</font></div>
<div><font face="courier new, monospace">c.numberToNumber = c.fun( { x: c.number } ).returns(c.number)</font></div><div><font face="courier new, monospace"><br></font></div><div><font color="#990000" face="courier new, monospace">// derive: returns a function that is the numerically-computed derivative</font></div>
<div><font color="#990000" face="courier new, monospace">// of the given function.</font></div><div><font face="courier new, monospace">var derive =</font></div><div><font color="#38761d" face="courier new, monospace"> </font><font color="#990000" face="courier new, monospace">/* This is the specification: */ </font></div>
<div><font face="courier new, monospace"> c.fun( { fn: c.numberToNumber },</font></div><div><font face="courier new, monospace"> { deltaX: c.number } )</font></div><div><font face="courier new, monospace"> .returns(c.numberToNumber)</font></div>
<div><font face="courier new, monospace"> .wrap(</font></div><div><font face="courier new, monospace"> <font color="#990000">/* And the implementation goes here: */ </font></font></div><div><font face="courier new, monospace"> function(fn, deltaX) { </font></div>
<div><font face="courier new, monospace"> return function(x) { </font></div><div><font face="courier new, monospace"> return (fn(x+deltaX/2) - fn(x-deltaX/2))/deltaX</font></div><div>
<font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"> })</font></div></blockquote><div><br>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):</div>
<div><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><div><font face="courier new, monospace"> </font><span style="color:rgb(153,0,0);font-family:'courier new',monospace">// Error: forgetting an argument:</span></div>
<div><font face="courier new, monospace"><font color="#990000"> </font>> derive(quadratic)</font></div><div><font face="courier new, monospace"> <font color="#ff0000">ContractError: Wrong number of arguments, expected 2 but got 1</font></font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> </font><span style="color:rgb(153,0,0);font-family:'courier new',monospace">// Error: calling with the arguments flipped:</span></div>
<div><font face="courier new, monospace"><font color="#990000"> </font>> derive(1.0, quadratic)</font></div><div><font face="courier new, monospace"> <font color="#ff0000">ContractError: Expected fun, but got 1</font></font></div>
<div><font color="#ff0000" face="courier new, monospace"> For the `fn` argument of the call.</font></div><div><font face="courier new, monospace"><br></font></div><div><span style="font-family:'courier new',monospace"> </span><span style="font-family:'courier new',monospace"> </span><font face="courier new, monospace"><font color="#990000">// Error: calling with the wrong kind of function:</font></font></div>
</div></div><div><div><font face="courier new, monospace"><font color="#990000"> </font>> var d = derive(function(x) { return "**" + x + "**" }, 1.0)</font></div></div><div><div>
<font face="courier new, monospace"><br></font></div></div><div><div><font face="courier new, monospace"> <font color="#990000">// The contract-checking shell is now installed around `fn` inside of `d`;</font></font></div>
</div><div><div><font color="#990000" face="courier new, monospace"> // throws an error when called:</font></div></div><div><div><font face="courier new, monospace"><font color="#990000"> </font>> d(100)</font></div>
</div><div><div><font face="courier new, monospace"> <font color="#ff0000">ContractError: `fn()` broke its contract</font></font></div></div><div><div><font color="#ff0000" face="courier new, monospace"> Expected number, but got '**100.5**'</font></div>
</div><div><div><font color="#ff0000" face="courier new, monospace"> for the return value of the call.</font></div></div></blockquote><font color="#ff0000" face="courier new, monospace"><br></font></div><div>
<br></div>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:<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">
<div><a href="https://github.com/sefaira/rho-contracts.js/blob/master/contract.face.js" target="_blank">https://github.com/sefaira/rho-contracts.js/blob/master/contract.face.js</a></div></blockquote><div><br></div><div>This has been in production at <a href="http://sefaira.com" target="_blank">sefaira.com</a> 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.</div>
<div><br></div><div><br></div><div>Best,</div><div><br></div><div>Guillaume</div><div><br></div><div><br></div><div><br><div><br></div><div><br></div></div></div>
<br>____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></blockquote></div><br></div>