|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
@import url(http://fonts.googleapis.com/css?family=Source+Code+Pro:200,400,600); |
|
|
|
html { |
|
min-width: 1040px; |
|
} |
|
|
|
body { |
|
font-family: "Source Code Pro", sans-serif; |
|
margin: 1em auto 4em auto; |
|
position: relative; |
|
width: 960px; |
|
color: #555; |
|
background: whiteSmoke; |
|
} |
|
|
|
h1 { |
|
font-size: 64px; |
|
font-weight: 200; |
|
letter-spacing: -6px; |
|
margin: .8em 0 .1em 0; |
|
-webkit-font-smoothing: antialiased; |
|
} |
|
|
|
h2 { |
|
font-size: 100%; |
|
margin-top: 2em; |
|
} |
|
|
|
h1, h2 { |
|
text-rendering: optimizeLegibility; |
|
} |
|
|
|
h2 a { |
|
color: #ccc; |
|
left: -20px; |
|
position: absolute; |
|
width: 740px; |
|
} |
|
|
|
h3, h4, h5 { |
|
font-size: 100%; |
|
font-weight: 400; |
|
margin-top: .8em; |
|
} |
|
|
|
h3, h4 { |
|
text-transform: uppercase; |
|
} |
|
|
|
h4 { |
|
color: #AAA; |
|
} |
|
|
|
footer { |
|
font-size: small; |
|
margin-top: 8em; |
|
} |
|
|
|
header aside { |
|
margin-top: 80px; |
|
} |
|
|
|
header aside, |
|
footer aside { |
|
text-align: right; |
|
} |
|
|
|
aside { |
|
font-size: small; |
|
right: 0; |
|
position: absolute; |
|
width: 180px; |
|
color: #AAA; |
|
} |
|
|
|
.attribution { |
|
font-size: small; |
|
margin-bottom: 2em; |
|
} |
|
|
|
i, cite, em, var, address, dfn { |
|
font-style: normal; |
|
border-bottom: 1px solid #CCC; |
|
} |
|
|
|
body > p, li > p { |
|
line-height: 1.5em; |
|
} |
|
|
|
body > p { |
|
width: 720px; |
|
} |
|
|
|
body > blockquote { |
|
width: 640px; |
|
} |
|
|
|
li { |
|
width: 680px; |
|
} |
|
|
|
a { |
|
color: steelblue; |
|
} |
|
|
|
a:not(:hover) { |
|
text-decoration: none; |
|
} |
|
|
|
pre, code, textarea { |
|
font-family: "Source Code Pro", monospace; |
|
color: #444; |
|
} |
|
|
|
code { |
|
line-height: 1em; |
|
} |
|
|
|
textarea { |
|
font-size: 100%; |
|
} |
|
|
|
body > pre { |
|
border-left: solid 2px #ccc; |
|
padding-left: 18px; |
|
margin: 2em 0 2em -20px; |
|
} |
|
|
|
.html .value, |
|
.javascript .string, |
|
.javascript .regexp { |
|
color: #756bb1; |
|
} |
|
|
|
.html .tag, |
|
.css .tag, |
|
.javascript .keyword { |
|
color: #3182bd; |
|
} |
|
|
|
.comment { |
|
color: #636363; |
|
} |
|
|
|
.html .doctype, |
|
.javascript .number { |
|
color: #31a354; |
|
} |
|
|
|
.html .attribute, |
|
.css .attribute, |
|
.javascript .class, |
|
.javascript .special { |
|
color: #e6550d; |
|
} |
|
|
|
svg { |
|
font: 10px sans-serif; |
|
} |
|
|
|
.axis path, .axis line { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
sup, sub { |
|
line-height: 0; |
|
} |
|
|
|
q:before, |
|
blockquote:before { |
|
content: "“"; |
|
} |
|
|
|
q:after, |
|
blockquote:after { |
|
content: "”"; |
|
} |
|
|
|
blockquote:before { |
|
position: absolute; |
|
left: 2em; |
|
} |
|
|
|
blockquote:after { |
|
position: absolute; |
|
} |
|
|
|
</style> |
|
<body> |
|
<h1>Quick Coffee</h1> |
|
<p>Examples and such to accompany J. Ashkenas' <a href="http://youtu.be/Kq5hmbjaBFk?t=11m45s">dotJS talk</a>. |
|
|
|
|
|
</p> |
|
<h2>Preliminaries</h2> |
|
<pre><code>{ok} = require 'assert'</code></pre> |
|
<p>A better comparator. See <a href="http://wiki.ecmascript.org/doku.php?id=harmony:egal">harmony docs</a>. |
|
|
|
</p> |
|
<pre><code>egal = (a, b) -> |
|
if a is b |
|
a isnt 0 or 1/a is 1/b |
|
else |
|
a isnt a and b isnt b |
|
|
|
eq = (a, b, msg) -> ok egal(a, b), msg ? a + ' is not ' + b</code></pre> |
|
<p>Yeah, we've got python roots. |
|
|
|
</p> |
|
<pre><code>print = console.log</code></pre> |
|
<h2>Samples</h2> |
|
<p>Catch error resulting from missing object/property. |
|
|
|
</p> |
|
<pre><code>result = try |
|
missing.property |
|
catch error |
|
"ERROR!"</code></pre> |
|
<p>Self-explanatory one-liners. |
|
|
|
</p> |
|
<pre><code>eq result, "ERROR!" |
|
|
|
eq 3, if one? then 2 else 3 |
|
|
|
eq 3, if one? |
|
2 |
|
else |
|
a = "alpha" |
|
if a? |
|
3 |
|
|
|
one = 1 |
|
|
|
eq 2, if one? then 2 else 3 |
|
|
|
eq 4, if b? then 2 else if c? then 3 else 4 |
|
|
|
eq [1..10][i-1], i for i in [1..10]</code></pre> |
|
<p>Sum the squares of first ten integers. |
|
|
|
</p> |
|
<pre><code>square = (x) -> x * x |
|
|
|
eq 385, (square i for i in [1..10]).reduce (x, y) -> x + y</code></pre> |
|
<h2>Ramping up</h2> |
|
<p>A quick demo of classes, decorators, and the fat arrow. |
|
|
|
</p> |
|
<pre><code>class Pirate |
|
|
|
constructor: (@name) -> |
|
|
|
hi: (name) -> |
|
"Hello there #{name}!" |
|
|
|
# Wrapped function. |
|
sayWithVigor = (f) -> |
|
(name) -> # new function to return |
|
f(name) + "!!!" |
|
|
|
ahoy: sayWithVigor (name) -> |
|
"Ahoy #{name}" |
|
|
|
do: (f) -> f()</code></pre> |
|
<p>Note use of "fat arrow" function binding (<code>=></code>) in the <code>say</code> method below. We're binding <code>@name</code> (i.e., <code>this.name</code>) to the unnamed method being passed as argument. |
|
|
|
</p> |
|
<pre><code>class Prisoner |
|
|
|
constructor: (@name, @captor) -> |
|
|
|
say: (words) -> |
|
"#{@name} says: #{words} ... #{@captor.name}'s got me!" |
|
|
|
hears: -> |
|
@captor.do => |
|
"Greetings, I am #{@captor.name}! You must be #{@name}. " + |
|
"#{@captor.ahoy @name}"</code></pre> |
|
<p>Here's what happens. |
|
|
|
</p> |
|
<pre><code>ahab = new Pirate('Ahab') |
|
mary = new Prisoner('Mary', captor=ahab) |
|
|
|
eq ahab.name, "Ahab" |
|
|
|
eq ahab.hi('Missy'), "Hello there Missy!" |
|
|
|
eq ahab.ahoy('Missy'), |
|
"Ahoy Missy!!!" |
|
|
|
eq mary.say("Oh no"), |
|
"Mary says: Oh no ... Ahab's got me!" |
|
|
|
eq mary.hears(), |
|
"Greetings, I am Ahab! You must be Mary. Ahoy Mary!!!"</code></pre> |
|
|