forked from jashkenas/coffeescript
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathindex.html
694 lines (579 loc) · 48.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<title>disnet/contracts.coffee @ GitHub</title>
<link href='http://fonts.googleapis.com/css?family=Gentium+Book+Basic' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>
<link href='documentation/contracts/styles/default.css' rel='stylesheet' type='text/css'>
<link href='documentation/contracts/styles/main.css' rel='stylesheet' type='text/css'>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-744645-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<a href="http://github.com/disnet/contracts.coffee"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
<div class="navigation">
<ul>
<li><a href="#basics">Basics</a></li>
<li><a href="#quickstart">Quick Start</a></li>
<li><a href="#resources">Resources</a></li>
<li><a href="#use">Use</a></li>
<li style="text-decoration: none;"> </li>
<li><a href="#simple">Simple</a></li>
<li><a href="#functions">Functions</a></li>
<li><a href="#objects">Objects</a></li>
<li><a href="#arrays">Arrays</a></li>
<li><a href="#operators">Operators</a></li>
<li style="text-decoration: none;"> </li>
<li><a href="#checking">Check-Time</a></li>
<li><a href="#naming">Naming</a></li>
<li><a href="#duck">Duck-Typing</a></li>
<li><a href="#log">Change Log</a></li>
<li style="text-decoration: none;"> </li>
<li><span id="try_button">Try it now!</span></li>
<li style="text-decoration: none;"> </li>
<li style="text-decoration: none;"> </li>
<li>
<div style="position: absolute; left: 35px">
<a href="http://www.mozilla.org/">
<img alt="Mozilla Research" style="height: 27px" src="documentation/images/moz-research.png">
</a>
</div>
</li>
</ul>
</div>
<div id="repl_container">
<div id="repl_editor">
<div id="repl_source_wrap">
<textarea id="repl_source"># Wrap the function in a contract that
# expects to be called with a number
# and will return a positive number as
# the result.
square :: (Num) -> Pos
square = (x) -> x * x
# Violates the contract by calling square
# with a string instead of a number.
square "42"</textarea>
<div id="run_button">Run!</div>
<div id="source_label" class="label">CoffeeScript</div>
</div>
<div id="repl_result_wrap">
<div id="result_label" class="label">JavaScript</div>
<pre id="repl_results"></pre>
</div>
<div style="clear: both"></div>
</div>
<div id="blame">
<div id="error_label" class="label">Errors</div>
<pre></pre></div>
</div>
<div id="main">
<div id="container">
<h1><a href="http://github.com/disnet/contracts.coffee">contracts.coffee</a>
</h1>
<p>Contracts.coffee is a dialect of <a href='http://jashkenas.github.com/coffee-script/'>CoffeeScript</a> with built-in support for contracts. It is inspired by the contract system found in <a href='http://racket-lang.org/'>Racket</a>.</p>
<p>Contracts let you clearly—even beautifully—express how your code behaves, and free you from writing tons of boilerplate, defensive code.</p>
<p>You can think of contracts as <code>assert</code> on steroids.</p>
<h2 id='basics'>Basics</h2>
<p>Here’s a simple example of a contract on a function:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>id</span> <span class='o'>::</span> <span class='nf'>(Num) -></span> <span class='nx'>Num</span>
<span class='nv'>id = </span><span class='nf'>(x) -></span> <span class='nx'>x</span>
</code></pre>
</div>
<p>This says that the <code>id</code> function should always be called with a number and will always return a number. It looks a lot like types (in fact the syntax looks a <em>lot</em> like Haskell) but unlike types, contracts are enforced at runtime in pure JavaScript.</p>
<p>If we try to use <code>id</code> incorrectly:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>id</span> <span class='s'>"foo"</span>
</code></pre>
</div>
<p>The program throws an error, which displays lots of nice information telling us what we did wrong:</p>
<pre style='color: red'>
Error: Contract violation: expected <Num>,
actual: "foo"
Value guarded in: id_module:42
-- blame is on: client_code:104
Parent contracts:
(Num) -> Num
</pre>
<p>You can also put contracts on objects.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>person</span> <span class='o'>::</span>
<span class='nv'>name: </span><span class='nx'>Str</span>
<span class='nv'>age: </span><span class='nx'>Num</span>
<span class='nv'>person =</span>
<span class='nv'>name: </span><span class='s'>"Bertrand Meyer"</span>
<span class='nv'>age: </span><span class='mi'>42</span>
</code></pre>
</div>
<p>And arrays.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>loc</span> <span class='o'>::</span> <span class='p'>[...</span><span class='nx'>Num</span><span class='p'>]</span>
<span class='nv'>loc = </span><span class='p'>[</span><span class='mi'>99332</span><span class='p'>,</span> <span class='mi'>23452</span><span class='p'>,</span> <span class='mi'>123</span><span class='p'>,</span> <span class='mi'>2</span><span class='p'>,</span> <span class='mi'>5000</span><span class='p'>]</span>
</code></pre>
</div>
<p>And in various combinations.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>average</span> <span class='o'>::</span> <span class='nf'>({name: Str, age: Num}, [...Num]) -></span> <span class='nx'>Str</span>
<span class='nv'>average = </span><span class='nf'>(person, loc) -></span>
<span class='nv'>sum = </span><span class='nx'>loc</span><span class='p'>.</span><span class='nx'>reduce</span> <span class='nf'>(s1, s2) -></span> <span class='nx'>s1</span> <span class='o'>+</span> <span class='nx'>s2</span>
<span class='s'>"</span><span class='si'>#{</span><span class='nx'>person</span><span class='p'>.</span><span class='nx'>name</span><span class='si'>}</span><span class='s'> wrote on average </span>
<span class='s'> </span><span class='si'>#{</span><span class='nx'>sum</span> <span class='o'>/</span> <span class='nx'>loc</span><span class='p'>.</span><span class='nx'>length</span><span class='si'>}</span><span class='s'> lines of code."</span>
</code></pre>
</div>
<p>Under the covers, contracts are really just normal functions that return <code>true</code> or <code>false</code>, so it’s really easy to roll your own by using the <code>!</code> operator to define new contracts.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nv'>Even = </span><span class='nf'>(x) -></span> <span class='nx'>x</span> <span class='o'>%</span> <span class='mi'>2</span> <span class='o'>is</span> <span class='mi'>0</span>
<span class='nv'>Odd = </span><span class='nf'>(x) -></span> <span class='nx'>x</span> <span class='o'>%</span> <span class='mi'>2</span> <span class='o'>isnt</span> <span class='mi'>0</span>
<span class='nx'>addEvens</span> <span class='o'>::</span> <span class='nf'>(!Even) -></span> <span class='o'>!</span><span class='nx'>Odd</span>
<span class='nv'>addEvens = </span><span class='nf'>(x) -></span> <span class='nx'>x</span> <span class='o'>+</span> <span class='mi'>1</span>
</code></pre>
</div>
<p>In fact, since contracts are checked at runtime, they can enforce properties that static type systems can only dream of.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nv'>Prime = </span><span class='nf'>(x) -></span> <span class='c1'># ...</span>
<span class='nx'>f</span> <span class='o'>::</span> <span class='nf'>(!Prime) -></span> <span class='o'>!</span><span class='nx'>Prime</span>
<span class='nv'>f = </span><span class='nf'>(x) -></span> <span class='nx'>x</span>
</code></pre>
</div>
<p>Eat your heart out, Haskell :)</p>
<span id='quickstart' />
<h2 id='quick_start'>Quick Start</h2>
<p>Here’s what you need to actually start working with contracts.coffee.</p>
<p>First, if you don’t already have them, install <a href='https://github.com/joyent/node/wiki/Installation'>Node.js</a> and <a href='http://npmjs.org/'>npm</a>. Then install contracts.coffee using npm:</p>
<div class='highlight'><pre><code class='bash'>npm install -g contracts.coffee
</code></pre>
</div>
<p>Now, compile some coffee with contracts!</p>
<div class='highlight'><pre><code class='bash'>coffee -c --contracts MyContractedScript.coffee
</code></pre>
</div>
<p>Note the <code>-c</code> and <code>--contracts</code> flags. The <code>-c</code> flag says to compile to JavaScript and <code>--contracts</code> enables contracts in the compiled JavaScript. If you don’t want contracts enabled (say in production) simply don’t include the <code>--contracts</code> flag.</p>
<p>If you are planning to run your code in the browser you will need to include the <code>contracts.js</code> library (which can be found <a href='https://github.com/disnet/contracts.coffee/blob/master/lib/contracts/contracts.js'>here</a>). So the header of your HTML file will look something like:</p>
<div class='highlight'><pre><code class='html'>...
<span class='nt'><script </span><span class='na'>src=</span><span class='s'>"lib/contracts.js"</span>
<span class='na'>type=</span><span class='s'>"application/javascript"</span><span class='nt'>></script></span>
<span class='nt'><script </span><span class='na'>src=</span><span class='s'>"MyContractedScript.js"</span>
<span class='na'>type=</span><span class='s'>"application/javascript"</span><span class='nt'>></script></span>
...
</code></pre>
</div>
<p>Contracts.coffee also has experimental support for <a href='http://requirejs.org/'>require.js</a>. Just load the “contracts” module first in <code>main.js</code>. So your <code>main.js</code> will look something like:</p>
<div class='highlight'><pre><code class='javascript'><span class='nx'>require</span><span class='p'>([</span><span class='s2'>"contracts"</span><span class='p'>,</span> <span class='s2'>"MyModule"</span><span class='p'>],</span> <span class='kd'>function</span><span class='p'>(</span><span class='nx'>c</span><span class='p'>,</span> <span class='nx'>myMod</span><span class='p'>)</span> <span class='p'>{</span>
<span class='c1'>// ...</span>
<span class='p'>});</span>
</code></pre>
</div>
<p>If you are planning to run your code on node.js then you simply need to install <code>contracts.js</code> via npm:</p>
<div class='highlight'><pre><code class='bash'>npm install contracts.js
</code></pre>
</div>
<p>Note that if you have an existing install of CoffeeScript, installing contracts.coffee will replace it. If you don’t want to give up the old CoffeeScript compiler you can grab the source from <a href='https://github.com/disnet/contracts.coffee'>github</a> and just run contracts.coffee from its own directory:</p>
<div class='highlight'><pre><code class='bash'>bin/coffee -c --contracts MyContractedScript.coffee
</code></pre>
</div>
<p>And finally, note that contracts.coffee requires some pretty new features of JavaScript to get its job done (in particular <a href='https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Proxy'>Proxies</a>) so it currently only works on Firefox 4+, Node.js 0.8.0+, and recent versions of Chrome (though at the moment you’ll need to enable the experimental JavaScript flag in about:flags).</p>
<p>When using node you will need to supply two command line flags to enable Proxies (<code>--harmony_proxies</code>) and WeakMaps (<code>--harmony-collections</code>). If you use the <code>coffee</code> or <code>cake</code> scripts these flags will be enabled automatically for you, otherwise the full process looks like:</p>
<div class='highlight'><pre><code class='bash'>coffee -c --contracts script.coffee
node --harmony_proxies --harmony-collections script.js
</code></pre>
</div>
<p>Note that since leaving off the <code>--contracts</code> flag will generate JavaScript code with absolutely no trace of contracts (the code is exactly what vanilla CoffeeScript would generate), you can easily set up a production build with contracts disabled that can run in any browser or JavaScript environment and a development/testing build with contracts enabled that you run in Firefox to help track down bugs.</p>
<h2 id='resources'>Resources</h2>
<ul>
<li><a href='https://github.com/disnet/contracts.coffee/issues?sort=created&direction=desc&state=open'>Issue Tracker</a> <br /> For filing bugs, requesting features and changes.</li>
<li><a href='https://groups.google.com/forum/?hl=en#!forum/contractscoffee'>Google Group</a> <br /> For general discussion about contracts.coffee.</li>
<li><a href='http://disnetdev.com/blog/'>disnet’s blog</a> <br /> Will sometimes post about contracts.coffee.</li>
</ul>
<span id='use' />
<h2 id='how_to_use'>How to Use</h2>
<p>In order to provide good error messages when things go wrong, contracts.coffee needs to know where contracted values are created and used in your code. It does this by enforcing a kind of module discipline and keeping track of which module a value was in when it was first wrapped up in a contract and which module uses the contracted value.</p>
<p>Since JavaScript doesn’t (yet) have modules, contracts.coffee must enforce a notion of modules on its own. The good news is that for the common cases you’ll never have to deal with this.</p>
<ul>
<li>
<p>If you are running in node.js the appropriate module wiring is done automatically. You just need to use <code>require</code> and the <code>exports</code> object like normal.</p>
</li>
<li>
<p>If you are running in the browser and using <a href='http://requirejs.org/'>require.js</a>, then the wiring is also automatically handled for you. Just be sure to include “contracts” as your first loaded module. (Here is an <a href='https://github.com/disnet/contracts.coffee/tree/master/test/webtest'>example</a> of this in action)</p>
</li>
<li>
<p>If you have some other situation then you will need to do the module wiring by hand. This is documented over <a href='https://github.com/disnet/contracts.coffee/wiki/Manual-Modules'>here</a>.</p>
</li>
</ul>
<span id='simple' />
<h2 id='simple_contracts'>Simple Contracts</h2>
<p>In addition to the <code>Num</code> contract that checks for numbers, we also have <code>Str</code>, <code>Bool</code>, <code>Null</code>, <code>Undefined</code>, <code>Nat</code>, <code>Pos</code>, <code>Neg</code>, <code>Any</code> (everything is ok), and <code>None</code> (nothing is ok).</p>
<h2 id='functions'>Functions</h2>
<p>Basic functions:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='nf'>(Num) -></span> <span class='nx'>Num</span>
<span class='nv'>f = </span><span class='nf'>(x) -></span> <span class='nx'>x</span>
</code></pre>
</div>
<p>Multiple arguments:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='nf'>(Num, Str, Bool) -></span> <span class='nx'>Num</span>
<span class='nv'>f = </span><span class='nf'>(n, s, b) -></span> <span class='c1'># ...</span>
</code></pre>
</div>
<p>Optional arguments:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='nf'>(Num, Str, Bool?) -></span> <span class='nx'>Num</span>
<span class='nv'>f = </span><span class='nf'>(n, s, b) -></span> <span class='c1'># ...</span>
</code></pre>
</div>
<p>All optional arguments must come at the end of the arguments list.</p>
<p>Higher order functions:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='p'>(</span><span class='nf'>(Num) -></span> <span class='nx'>Bool</span><span class='p'>,</span> <span class='nx'>Num</span><span class='p'>)</span> <span class='o'>-></span> <span class='nx'>Bool</span>
<span class='nv'>f = </span><span class='nf'>(g, n) -></span> <span class='c1'># ...</span>
</code></pre>
</div>
<p>Functions that <em>cannot</em> be called with the <code>new</code> keyword:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='p'>(</span><span class='nx'>Num</span><span class='p'>)</span> <span class='o'>--></span> <span class='nx'>Num</span>
<span class='nv'>f = </span><span class='nf'>(n) -></span> <span class='c1'># ...</span>
<span class='c1'>#...</span>
<span class='nv'>g = </span><span class='nx'>f</span> <span class='mi'>42</span> <span class='c1'># ok</span>
<span class='nv'>g = </span><span class='k'>new</span> <span class='nx'>f</span> <span class='mi'>42</span> <span class='c1'># error!</span>
</code></pre>
</div>
<p>Functions that can <em>only</em> be called with the <code>new</code> keyword:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='p'>(</span><span class='nx'>Num</span><span class='p'>)</span> <span class='o'>==></span> <span class='nx'>Num</span>
<span class='nv'>f = </span><span class='nf'>(n) -></span> <span class='c1'># ...</span>
<span class='c1'>#...</span>
<span class='nv'>g = </span><span class='nx'>f</span> <span class='mi'>42</span> <span class='c1'># error!</span>
<span class='nv'>g = </span><span class='k'>new</span> <span class='nx'>f</span> <span class='mi'>42</span> <span class='c1'># ok</span>
</code></pre>
</div>
<p>Dependent functions:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>inc</span> <span class='o'>::</span> <span class='nf'>(Num) -></span> <span class='o'>!</span><span class='nf'>(result, args) -></span> <span class='nx'>result</span> <span class='o'>></span> <span class='nx'>args</span><span class='p'>[</span><span class='mi'>0</span><span class='p'>]</span>
<span class='nv'>inc = </span><span class='nf'>(n) -></span> <span class='nx'>n</span> <span class='o'>+</span> <span class='mi'>1</span>
</code></pre>
</div>
<p>The variable <code>args[0]</code> is the first argument passed to the function (<code>args[1]</code> would be the second argument, <code>args[2]</code> the third, and so on). This allows us to compare the result of the function to its arguments. Note that the test is run after the function has completed so if any of the arguments were mutated during the function’s execution the test could give spurious results.</p>
<p>The <code>this</code> contract:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='nf'>(Str, @{name: Str}) -></span> <span class='nx'>Str</span>
<span class='nv'>f = </span><span class='nf'>(s) -></span> <span class='c1'>#...</span>
<span class='nv'>o = </span><span class='p'>{</span> <span class='nv'>name: </span><span class='s'>"foo"</span><span class='p'>,</span> <span class='nv'>f: </span><span class='nx'>f</span><span class='p'>}</span>
<span class='nx'>o</span><span class='p'>.</span><span class='nx'>f</span><span class='p'>()</span>
</code></pre>
</div>
<p>Checks that <code>this</code> matches the given object contract.</p>
<h2 id='objects'>Objects</h2>
<p>Simple properties:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span>
<span class='nv'>a: </span><span class='nx'>Str</span>
<span class='nv'>b: </span><span class='nx'>Num</span>
<span class='nv'>f: </span><span class='nf'>(Num) -></span> <span class='nx'>Num</span>
<span class='nv'>o =</span>
<span class='nv'>a: </span><span class='s'>"foo"</span>
<span class='nv'>b: </span><span class='mi'>42</span>
<span class='nv'>f: </span><span class='nf'>(x) -></span> <span class='nx'>x</span>
</code></pre>
</div>
<p><strong>Note:</strong> Putting an object contract on a primitive will always fail. This might seem obvious at first but since many primitives have methods, the following contract would seem reasonable:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='p'>({</span><span class='nv'>toString: </span><span class='nf'>(Any) -></span> <span class='nx'>Str</span><span class='p'>})</span> <span class='o'>-></span> <span class='nx'>Str</span>
<span class='nv'>f = </span><span class='nf'>(s) -></span> <span class='nx'>s</span><span class='p'>.</span><span class='nx'>toString</span><span class='p'>()</span>
<span class='nx'>f</span> <span class='s'>"a string"</span> <span class='c1'># Contract violation</span>
<span class='nx'>f</span> <span class='p'>{}</span> <span class='c1'># ok</span>
</code></pre>
</div>
<p>Even though “a string” has a <code>toString</code> method the contract will always signal a violation. This is because JavaScript proxies can wrap objects but not primitives.</p>
<p>In addition due to a limitation in the current JavaScript engines implementations of proxies, you cannot put a contract on the <code>Date</code> object. This is expected to be fixed in future implementations. See <a href='https://github.com/disnet/contracts.coffee/issues/44'>this issue</a> to track progress on this.</p>
<p>Optional properties:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span>
<span class='nv'>a: </span><span class='nx'>Str</span>
<span class='nv'>b: </span><span class='nx'>Num</span><span class='o'>?</span>
<span class='nv'>f: </span><span class='nf'>(Num) -></span> <span class='nx'>Num</span>
<span class='nv'>o =</span>
<span class='nv'>a: </span><span class='s'>"foo"</span>
<span class='nv'>f: </span><span class='nf'>(x) -></span> <span class='nx'>x</span>
</code></pre>
</div>
<p>Nested objects:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span>
<span class='nv'>oo: </span><span class='p'>{</span> <span class='nv'>a: </span><span class='nx'>Str</span> <span class='p'>}</span>
<span class='nv'>b: </span><span class='nx'>Num</span>
<span class='nv'>o =</span>
<span class='nv'>oo: </span><span class='p'>{</span> <span class='nv'>a: </span><span class='s'>"foo"</span> <span class='p'>}</span>
<span class='nv'>b: </span><span class='mi'>42</span>
</code></pre>
</div>
<p>Recursive objects:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span>
<span class='nv'>a: </span><span class='nx'>Num</span>
<span class='nv'>b: </span><span class='nx'>Self</span>
<span class='nv'>c: </span><span class='nf'>(Num) -></span> <span class='nx'>Self</span>
<span class='nv'>inner: </span><span class='p'>{</span> <span class='nv'>y: </span><span class='nx'>Bool</span><span class='p'>,</span> <span class='nv'>z: </span><span class='nx'>Self</span> <span class='p'>}</span>
<span class='nv'>o = </span><span class='c1'>#...</span>
</code></pre>
</div>
<p><code>Self</code> binds to the closest object contract. So in this example, <code>Self</code> in <code>b</code> and <code>c</code> points to <code>o</code> and <code>Self</code> in <code>inner.z</code> points to <code>inner</code>.</p>
<p>Objects with functions that have pre and post conditions:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span>
<span class='nv'>a: </span><span class='nx'>Num</span>
<span class='nv'>f: </span><span class='nf'>(Num) -></span> <span class='nx'>Num</span> <span class='o'>-|</span>
<span class='nv'>pre: </span><span class='nf'>(o) -></span> <span class='nx'>o</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'>></span> <span class='mi'>10</span>
<span class='nv'>post: </span><span class='nf'>(o) -></span> <span class='nx'>o</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'>></span> <span class='mi'>20</span>
<span class='nv'>o =</span>
<span class='nv'>a: </span><span class='mi'>12</span>
<span class='nv'>f: </span><span class='nf'>(x) -></span> <span class='nx'>@</span><span class='p'>.</span><span class='nv'>a = </span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'>+</span> <span class='nx'>x</span>
</code></pre>
</div>
<p>The pre and post condition functions are called with the object that <code>f</code> is a member of. As their names imply, <code>pre</code> is called before the function <code>f</code> is invoked and <code>post</code> is called after.</p>
<p>Object invariants:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span>
<span class='nv'>a: </span><span class='nx'>Num</span>
<span class='nv'>f: </span><span class='nf'>(Num) -></span> <span class='nx'>Num</span> <span class='o'>-|</span>
<span class='nv'>pre: </span><span class='nf'>(o) -></span> <span class='nx'>o</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'>></span> <span class='mi'>10</span>
<span class='nv'>post: </span><span class='nf'>(o) -></span> <span class='nx'>o</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'>></span> <span class='mi'>20</span>
<span class='o'>-|</span> <span class='nv'>invariant: </span><span class='o'>-></span>
<span class='nx'>@</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'>></span> <span class='mi'>0</span> <span class='o'>and</span> <span class='nx'>@</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'><</span> <span class='mi'>100</span>
<span class='nv'>o =</span>
<span class='nv'>a: </span><span class='mi'>12</span>
<span class='nv'>f: </span><span class='nf'>(x) -></span> <span class='nx'>@</span><span class='p'>.</span><span class='nv'>a = </span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>a</span> <span class='o'>+</span> <span class='nx'>x</span>
</code></pre>
</div>
<p>The invariant is checked at contract application and whenever there is a possibility of <code>o</code> mutating (on property sets and delete).</p>
<h2 id='arrays'>Arrays</h2>
<p><strong>Note: due to a proxy bug in all the current JavaScript engines, arrays are not currently being wrapped in a contract. This won’t cause code to fail, it just means that contracts will not be checked for arrays. See this github <a href='https://github.com/disnet/contracts.coffee/issues/54'>issue</a> for more info.</strong></p>
<p>Basic arrays:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>a</span> <span class='o'>::</span> <span class='p'>[</span><span class='nx'>Num</span><span class='p'>,</span> <span class='nx'>Str</span><span class='p'>,</span> <span class='p'>[</span><span class='nx'>Bool</span><span class='p'>,</span> <span class='nx'>Num</span><span class='p'>]]</span>
<span class='nv'>a = </span><span class='p'>[</span><span class='mi'>42</span><span class='p'>,</span> <span class='s'>"foo"</span><span class='p'>,</span> <span class='p'>[</span><span class='kc'>true</span><span class='p'>,</span> <span class='mi'>24</span><span class='p'>]</span>
</code></pre>
</div>
<p>This says the array must have three elements, the first being a <code>Num</code>, the second being a <code>Str</code>, and the third being another array.</p>
<p>Multiple elements:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>a</span> <span class='o'>::</span> <span class='p'>[...</span><span class='nx'>Num</span><span class='p'>]</span>
<span class='nv'>a = </span><span class='p'>[</span><span class='mi'>42</span><span class='p'>,</span> <span class='mi'>24</span><span class='p'>,</span> <span class='mi'>432</span><span class='p'>,</span> <span class='mi'>854</span><span class='p'>,</span> <span class='mi'>21</span><span class='p'>]</span>
</code></pre>
</div>
<p>The <code>...</code> operator says that the array will only contain <code>Num</code>s.</p>
<p>Mixing arrays</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>a</span> <span class='o'>::</span> <span class='p'>[</span><span class='nx'>Bool</span><span class='p'>,</span> <span class='nx'>Str</span><span class='p'>,</span> <span class='p'>...</span><span class='nx'>Num</span><span class='p'>]</span>
<span class='nv'>a = </span><span class='p'>[</span><span class='kc'>false</span><span class='p'>,</span> <span class='s'>"foo"</span><span class='p'>,</span> <span class='mi'>432</span><span class='p'>,</span> <span class='mi'>854</span><span class='p'>,</span> <span class='mi'>21</span><span class='p'>]</span>
</code></pre>
</div>
<p>The <code>...</code> operator can be mixed with single contracts. This says that the array’s first and second positions must pass the first two contracts and the remaining array positions must pass <code>Num</code>. The <code>...</code> operator must be in the last position of the array contract.</p>
<span id='operators' />
<h2 id='contract_operators'>Contract Operators</h2>
<p>The <code>or</code> contract:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span> <span class='p'>{</span> <span class='nv'>a: </span><span class='nx'>Num</span> <span class='o'>or</span> <span class='nx'>Str</span> <span class='p'>}</span>
<span class='nv'>o = </span><span class='p'>{</span> <span class='nv'>a: </span><span class='mi'>42</span> <span class='p'>}</span>
</code></pre>
</div>
<p>Here, the <code>a</code> property must pass either the <code>Num</code> or <code>Str</code> contract. Note that since contracts like function and object have deferred checking, they cannot be used with the <code>or</code> contract. Or to be more precise only <em>one</em> function/object contract can be used with <code>or</code>. So you could have <code>Num or (Num) -> Num</code> but not <code>((Num) -> Num) or ((Str) -> Str)</code>. If you combine normal contracts and function/object contracts with <code>or</code> all the normal contracts will be checked first and then the function/object contract will be applied.</p>
<p>The <code>and</code> contract:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>o</span> <span class='o'>::</span> <span class='p'>{</span> <span class='nv'>a: </span><span class='nx'>Num</span> <span class='o'>and</span> <span class='nx'>Even</span> <span class='p'>}</span>
<span class='nv'>o = </span><span class='p'>{</span> <span class='nv'>a: </span><span class='mi'>42</span> <span class='p'>}</span>
</code></pre>
</div>
<p>The <code>a</code> property must pass both the <code>Num</code> and <code>Even</code> contracts. Just like <code>or</code> you cannot use multiple function/object contracts with <code>and</code>.</p>
<span id='checking' />
<h2 id='checktime_of_contracts'>Check-Time of Contracts</h2>
<p>The actual point in time when a contract is checked depends on the kind of contract.</p>
<ul>
<li>Simple contracts (<em>e.g.</em> <code>Num</code>, <code>Str</code>, and contracts created via <code>!</code>) are checked immediately.</li>
<li>Function contracts are checked when the function is called.</li>
<li>Object contracts are immediately checked to make sure all their properties exist. The individual property contracts are checked each time the property is accessed.</li>
<li>Array contracts are checked in the same way as object contracts.</li>
</ul>
<p>For example, this means that if a function <code>f</code> takes another function <code>g</code> as an argument, it will delay checking of <code>g</code> until <code>g</code> is actually invoked.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='p'>(</span><span class='nf'>(Num) -></span> <span class='nx'>Num</span><span class='p'>,</span> <span class='nf'>(Str) -></span> <span class='nx'>Str</span><span class='p'>)</span> <span class='o'>-></span> <span class='nx'>Num</span>
<span class='nv'>f = </span><span class='nf'>(g, h) -></span> <span class='nx'>g</span> <span class='mi'>42</span>
<span class='nv'>str = </span><span class='nf'>(x) -></span> <span class='s'>"string"</span>
<span class='nv'>num = </span><span class='nf'>(x) -></span> <span class='mi'>42</span>
<span class='nx'>f</span> <span class='nx'>str</span><span class='p'>,</span> <span class='nx'>num</span> <span class='c1'># fails when g is called inside f</span>
<span class='nx'>f</span> <span class='nx'>num</span><span class='p'>,</span> <span class='nx'>num</span> <span class='c1'># since h is never called it never fails</span>
<span class='c1'># even though it would violate its contract</span>
</code></pre>
</div>
<p>A function returning an object will immediately check for the existence of properties but delay checking that they match their contract until accessed.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>f</span> <span class='o'>::</span> <span class='nf'>(Num) -></span> <span class='p'>{</span><span class='nv'>a: </span><span class='nx'>Str</span><span class='p'>,</span> <span class='nv'>b: </span><span class='nx'>Num</span><span class='p'>}</span>
<span class='nv'>f = </span><span class='nf'>(x) -></span> <span class='p'>{</span><span class='nv'>a: </span><span class='s'>"foo"</span><span class='p'>}</span>
<span class='c1'># fails as soon as f returns since b is missing</span>
<span class='nx'>f</span> <span class='mi'>42</span>
<span class='nx'>g</span> <span class='o'>::</span> <span class='nf'>(Num) -></span> <span class='p'>{</span><span class='nv'>a: </span><span class='nx'>Str</span><span class='p'>,</span> <span class='nv'>b: </span><span class='nx'>Num</span><span class='p'>}</span>
<span class='nv'>g = </span><span class='nf'>(x) -></span> <span class='p'>{</span><span class='nv'>a: </span><span class='nx'>x</span><span class='p'>,</span> <span class='nv'>b: </span><span class='nx'>x</span><span class='p'>}</span>
<span class='nv'>o = </span><span class='nx'>g</span> <span class='mi'>42</span> <span class='c1'># does not fail yet</span>
<span class='nx'>console</span><span class='p'>.</span><span class='nx'>log</span> <span class='nx'>o</span><span class='p'>.</span><span class='nx'>a</span> <span class='c1'># now fails because o.a does not satisfy Str</span>
</code></pre>
</div><span id='naming' />
<h2 id='naming_your_own_contracts'>Naming your own contracts</h2>
<p>You can bind a contract to a variable just like normal expressions:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nv'>NumId = </span><span class='o'>?</span><span class='nf'>(Num) -></span> <span class='nx'>Num</span>
<span class='nx'>f</span> <span class='o'>::</span> <span class='nx'>NumId</span>
<span class='nv'>f = </span><span class='nf'>(x) -></span> <span class='nx'>x</span>
</code></pre>
</div>
<p>The <code>?</code> operator allows you to escape out of the normal expression language and into the contract language.</p>
<p>You can also escape from the contract language to the normal expression language:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>takesEvens</span> <span class='o'>::</span> <span class='p'>(</span><span class='o'>!</span><span class='nf'>(x) -></span> <span class='nx'>x</span> <span class='o'>%</span> <span class='mi'>2</span> <span class='o'>is</span> <span class='mi'>0</span><span class='p'>)</span> <span class='o'>-></span> <span class='nx'>Num</span>
<span class='nv'>takesEvens = </span><span class='nf'>(x) -></span> <span class='nx'>x</span>
</code></pre>
</div>
<p>The result of the expression in the <code>!</code> escape must be a function that returns a boolean. It is converted to a contract that checks its value against the function.</p>
<p>The standard <code>Num</code> and <code>Str</code> contracts you have seen are implemented as:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nv'>Num = </span><span class='o'>?!</span><span class='nf'>(x) -></span> <span class='k'>typeof</span> <span class='nx'>x</span> <span class='o'>is</span> <span class='s'>'number'</span>
<span class='nv'>Str = </span><span class='o'>?!</span><span class='nf'>(x) -></span> <span class='k'>typeof</span> <span class='nx'>x</span> <span class='o'>is</span> <span class='s'>'string'</span>
</code></pre>
</div>
<p>The syntax may look a little strange at first, but it can be read as “assign to <code>Num</code> the contract generated from the function <code>(x) ->
...</code></p>
<p>It could also be written:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nv'>Num = </span><span class='nf'>(x) -></span> <span class='k'>typeof</span> <span class='nx'>x</span> <span class='o'>is</span> <span class='s'>'number'</span>
<span class='nv'>Str = </span><span class='nf'>(x) -></span> <span class='k'>typeof</span> <span class='nx'>x</span> <span class='o'>is</span> <span class='s'>'string'</span>
<span class='nv'>f = </span><span class='nf'>(!Num) -></span> <span class='o'>!</span><span class='nx'>Str</span>
</code></pre>
</div><span id='duck' />
<h2 id='ducktyping_invariants'>Duck-Typing Invariants</h2>
<p>A full write-up on this topic is covered <a href='http://disnetdev.com/blog/2011/09/05/Duck-Typing-Invariants-In-contracts.coffee/'>here</a> but to whet your appetite: you can “duck-type” object invariants. Code can now say, “give me whatever object you want so long as it has <em>these</em> properties and satisfies <em>these</em> invariants”.</p>
<p>Consider a binary search tree:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='c1'># A binary search tree is a binary tree </span>
<span class='c1'># where each node is greater than the </span>
<span class='c1'># left child but less than the right child</span>
<span class='nv'>BinarySearchTree = </span><span class='o'>?</span><span class='p'>(</span><span class='nx'>Null</span> <span class='o'>or</span> <span class='p'>{</span>
<span class='nv'>node: </span><span class='nx'>Num</span>
<span class='nv'>left: </span><span class='nx'>Self</span> <span class='o'>or</span> <span class='nx'>Null</span>
<span class='nv'>right: </span><span class='nx'>Self</span> <span class='o'>or</span> <span class='nx'>Null</span>
<span class='o'>-|</span> <span class='nv'>invariant: </span><span class='o'>-></span>
<span class='p'>(</span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>node</span> <span class='o'>></span> <span class='nx'>@</span><span class='p'>.</span><span class='nx'>left</span><span class='p'>.</span><span class='nx'>node</span><span class='p'>)</span> <span class='o'>and</span> <span class='p'>(</span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>node</span> <span class='o'><</span> <span class='nx'>@</span><span class='p'>.</span><span class='nx'>right</span><span class='p'>.</span><span class='nx'>node</span><span class='p'>)</span>
<span class='p'>})</span>
</code></pre>
</div>
<p>And a <a href='http://en.wikipedia.org/wiki/Red-black_tree'>red-black tree</a>:</p>
<div class='highlight'><pre><code class='coffeescript'><span class='c1'># A red-black tree is a binary search tree </span>
<span class='c1'># that keeps its balance</span>
<span class='nv'>RedBlackTree = </span><span class='o'>?</span><span class='p'>(</span><span class='nx'>Null</span> <span class='o'>or</span> <span class='p'>{</span>
<span class='nv'>node: </span><span class='nx'>Num</span>
<span class='nv'>color: </span><span class='nx'>Str</span>
<span class='nv'>left: </span><span class='nx'>Self</span> <span class='o'>or</span> <span class='nx'>Null</span>
<span class='nv'>right: </span><span class='nx'>Self</span> <span class='o'>or</span> <span class='nx'>Null</span>
<span class='o'>-|</span> <span class='nv'>invariant: </span><span class='o'>-></span>
<span class='p'>(</span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>color</span> <span class='o'>is</span> <span class='s'>"red"</span> <span class='o'>or</span> <span class='nx'>@</span><span class='p'>.</span><span class='nx'>color</span> <span class='o'>is</span> <span class='s'>"black"</span><span class='p'>)</span> <span class='o'>and</span>
<span class='p'>(</span><span class='k'>if</span> <span class='nx'>@</span><span class='p'>.</span><span class='nx'>color</span> <span class='o'>is</span> <span class='s'>"red"</span>
<span class='p'>(</span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>left</span><span class='p'>.</span><span class='nx'>color</span> <span class='o'>is</span> <span class='s'>"black"</span> <span class='o'>and</span>
<span class='nx'>@</span><span class='p'>.</span><span class='nx'>right</span><span class='p'>.</span><span class='nx'>color</span> <span class='o'>is</span> <span class='s'>"black"</span><span class='p'>)</span>
<span class='k'>else</span>
<span class='kc'>true</span>
<span class='p'>)</span> <span class='o'>and</span>
<span class='p'>(</span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>node</span> <span class='o'>>=</span> <span class='nx'>@</span><span class='p'>.</span><span class='nx'>left</span><span class='p'>.</span><span class='nx'>node</span><span class='p'>)</span> <span class='o'>and</span>
<span class='p'>(</span><span class='nx'>@</span><span class='p'>.</span><span class='nx'>node</span> <span class='o'>>=</span> <span class='nx'>@</span><span class='p'>.</span><span class='nx'>right</span><span class='p'>.</span><span class='nx'>node</span><span class='p'>)</span> <span class='o'>and</span>
<span class='p'>})</span>
</code></pre>
</div>
<p>The red-black tree is exactly the same as a binary search tree with some additional invariants. This means we have a kind of subtyping going on here: code that expects a binary search tree will also work with a red-black tree but <em>not</em> vica versa.</p>
<div class='highlight'><pre><code class='coffeescript'><span class='nx'>takesBST</span> <span class='o'>::</span> <span class='nf'>(BinarySearchTree) -></span> <span class='nx'>Any</span>
<span class='nv'>takesBST = </span><span class='nf'>(bst) -></span> <span class='p'>...</span>
<span class='nx'>takesRedBlack</span> <span class='o'>::</span> <span class='nf'>(RedBlackTree) -></span> <span class='nx'>Any</span>
<span class='nv'>takesRedBlack = </span><span class='nf'>(rbTree) -></span> <span class='p'>...</span>
<span class='nv'>bst = </span><span class='nx'>makeBinarySearchTree</span><span class='p'>()</span>
<span class='nv'>rb = </span><span class='nx'>makeRedBlackTree</span><span class='p'>()</span>
<span class='nx'>takesBST</span> <span class='nx'>bst</span> <span class='c1'># works fine</span>
<span class='nx'>takesBST</span> <span class='nx'>rb</span> <span class='c1'># works fine</span>
<span class='nx'>takesRedBlack</span> <span class='nx'>rb</span> <span class='c1'># works fine</span>
<span class='nx'>takesRedBlack</span> <span class='nx'>bst</span> <span class='c1'># might fail if the full </span>
<span class='c1'># red-black invariants don't hold!</span>
</code></pre>
</div>
<p>In duck-typing, functions work when given <em>any</em> object that has the properties the function needs (though the object might have other properties too). Contracts allow us to extend that to object invariants: functions work when given <em>any</em> object that has the required properties <em>and</em> satisfies the required invariants (though the object might satisfy other invariants too).</p>
<span id='log' />
<h2 id='change_log'>Change Log</h2>
<ul>
<li>
<p><a href='https://github.com/disnet/contracts.coffee/tree/c0.3.1'>0.3.2</a> (September 5, 2012)</p>
<ul>
<li>disabling contracts for arrays (see issue <a href='https://github.com/disnet/contracts.coffee/issues/54'>54</a>)</li>
<li>various bug fixes</li>
</ul>
</li>
<li>
<p><a href='https://github.com/disnet/contracts.coffee/tree/c0.3.1'>0.3.1</a> (July 15th, 2012)</p>
<ul>
<li>support for stable node.js (v0.8.0+)</li>
<li>some bug fixes</li>
</ul>
</li>
<li>
<p><a href='https://github.com/disnet/contracts.coffee/tree/c0.3.0'>0.3.0</a> (March 15th, 2012)</p>
<ul>
<li><a href='https://github.com/disnet/contracts.coffee/issues/8'>change</a> to dependent function contracts</li>
<li>various contracts.coffee bug fixes: <a href='https://github.com/disnet/contracts.coffee/issues/27'>#27</a>, <a href='https://github.com/disnet/contracts.coffee/issues/41'>#41</a>, <a href='https://github.com/disnet/contracts.coffee/issues/33'>#33</a>, <a href='https://github.com/disnet/contracts.coffee/issues/31'>#31</a>,</li>
<li>various contracts.js bug fixes: <a href='https://github.com/disnet/contracts.js/pull/9'>#9</a>, <a href='https://github.com/disnet/contracts.js/pull/8'>#8</a>, <a href='https://github.com/disnet/contracts.js/pull/7'>#7</a>, <a href='https://github.com/disnet/contracts.js/pull/6'>#6</a>, <a href='https://github.com/disnet/contracts.js/pull/5'>#5</a>, <a href='https://github.com/disnet/contracts.js/pull/4'>#4</a></li>
<li>experimental support for require.js (see <a href='https://github.com/disnet/contracts.coffee/tree/master/test/webtest'>here</a> for example use)</li>
<li>based off CoffeeScript 1.3.1</li>
</ul>
</li>
<li>
<p><a href='https://github.com/disnet/contracts.coffee/tree/c0.2.0'>0.2.0</a> (January 4th, 2012)</p>
<ul>
<li>removed <code>.use()</code>, now using <code>Contracts.exports</code> and <code>Contracts.use</code></li>
<li>various bug fixes</li>
<li>based off CoffeeScript 1.2.0</li>
</ul>
</li>
<li>
<p><a href='https://github.com/disnet/contracts.coffee/tree/c0.1.0'>0.1.0</a> (August 29th, 2011)</p>
<ul>
<li>initial release</li>
<li>based off CoffeeScript 1.1.2</li>
</ul>
</li>
</ul>
<div class="footer">
get the source code on GitHub : <a href="http://github.com/disnet/contracts.coffee">disnet/contracts.coffee</a>
<div>
</div>
</div>
</div>
</div>
<script type="text/coffeescript">
compileSource = ->
source = $('#repl_source').val()
window.compiledJS = ''
try
window.bareCompiledJS = CoffeeScript.compile source, { bare: on, contracts: on }
window.compiledJS = CoffeeScript.compile source, { bare: off, contracts: on }
el = $('#repl_results')[0]
if el.innerText
el.innerText = window.bareCompiledJS
else
$(el).text window.bareCompiledJS
$('#blame pre').text("")
catch error
$('#blame pre').text(error.message)
closeMenu = ->
$("#repl_container").removeClass "active"
$("#try_button").click ->
if $("#repl_container").hasClass('active')
closeMenu()
else
closeMenu()
$("#repl_container").addClass 'active'
false
# Eval the compiled js.
evalJS = ->
if typeof window.Proxy is 'undefined'
$('#blame pre').text "Your browser does not yet support Proxies which are required to run contracts.coffee.\nProxies currently work in Firefox 4+ with support for Chrome coming soon."
return false
try
eval window.compiledJS
catch error
$('#blame pre').text(error.message)
# Listen for keypresses and recompile.
$('#repl_source').keyup -> compileSource()
$('#run_button').click evalJS
# Dismiss console if Escape pressed or click falls outside console
# Trigger Run button on Ctrl-Enter
$(document.body)
.keydown (e) ->
closeMenu() if e.which == 27
evalJS() if e.which == 13 and (e.metaKey or e.ctrlKey) # and $('.minibutton.run:visible').length
.click (e) ->
return false if $(e.target).closest("#repl_container").length > 0
closeMenu()
$(document).ready ->
compileSource()
</script>
<script src="documentation/vendor/jquery-1.6.4.js"></script>
<script src="extras/coffee-script.js"></script>
<script src="lib/contracts/contracts.js"></script>
</body>
</html>