coffeescript
DESCRIPTION
I discovered CoffeeScript during a recent project that Jim Garvin and I were working on. We knew the app was going to be heavy on the JavaScript, and that’s how we started – writing straight JavaScript. Even though I have written JavaScript for years, this time, the JavaScript syntax itself got in the way. CoffeeScript’s elegant syntax relieved the burden.I quickly fell so in love with CoffeeScript that I have since sworn off writing raw JavaScript directly ever again. The goal of this talk is to convince the audience to try CoffeeScript in hopes that they too will find it as valuable as I did.TRANSCRIPT
![Page 1: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/1.jpg)
CoffeeScriptJavaScript's Less Ostentatious Kid Brother
Ryan McGearyhttp://ryan.mcgeary.org
@rmm5t
1
![Page 2: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/2.jpg)
Jeremy Ashkenas
http://jashkenas.github.com/coffee-script/
JavaScript's less ostentatious kid brother
one-to-onewith JavaScript
better functional syntax
compiles tothe good parts
2
![Page 3: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/3.jpg)
if (typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!");}
3
![Page 4: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/4.jpg)
alert "I knew it!" if elvis?
3
![Page 5: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/5.jpg)
var cube, square;square = function(x) { return x * x;};cube = function(x) { return square(x) * x;};
4
![Page 6: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/6.jpg)
square = (x) -> x * xcube = (x) -> square(x) * x
4
![Page 7: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/7.jpg)
var _i, _len, _ref, _result, food, lunch;lunch = (function() { _result = []; _ref = ['toast', 'cheese', 'wine']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { food = _ref[_i]; _result.push(eat(food)); } return _result;})();
5
![Page 8: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/8.jpg)
lunch = (eat food for food in ['toast', 'cheese', 'wine'])
5
![Page 9: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/9.jpg)
var _i, _j, _len, _len2, _ref, _ref2, roid, roid2;_ref = asteroids;for (_i = 0, _len = _ref.length; _i < _len; _i++) { roid = _ref[_i]; _ref2 = asteroids; for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { roid2 = _ref2[_j]; if (roid !== roid2) { if (roid.overlaps(roid2)) { roid.explode(); } } }}
6
![Page 10: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/10.jpg)
for roid in asteroids for roid2 in asteroids when roid isnt roid2 roid.explode() if roid.overlaps roid2
6
![Page 11: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/11.jpg)
Installation
$ brew install npm
# Add /usr/local/share/npm/bin to PATH
$ npm install coffee-script
7
![Page 12: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/12.jpg)
Usage
$ coffee -c path/to/script.coffee
$ coffee --watch experimental.coffee
$ coffee --print *.coffee > all.js
8
![Page 13: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/13.jpg)
if happy and knowsIt clapsHands() chaChaCha()else showIt()
Significant Whitespace
9
![Page 14: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/14.jpg)
if (happy && knowsIt) { clapsHands(); chaChaCha();} else { showIt();}
Significant Whitespace
9
![Page 15: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/15.jpg)
Functions
square = (x) -> x * x
area = (x, y) -> x * y
noop = ->
10
![Page 16: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/16.jpg)
Functionsvar area, noop, square;square = function(x) { return x * x;};area = function(x, y) { return x * y;};noop = function() {};
10
![Page 17: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/17.jpg)
Objects
kids = brother: name: "Max" age: 11 sister: name: "Ida" age: 9
var kids;kids = { brother: { name: "Max", age: 11 }, sister: { name: "Ida", age: 9 }};
>>
11
![Page 18: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/18.jpg)
Lexical Scoping / Variable Safety
outer = 1change = -> inner = -1 outer = 10inner = change()
(function() { var change, inner, outer; outer = 1; change = function() { var inner; inner = -1; return (outer = 10); }; inner = change();}).call(this);
>>
12
![Page 19: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/19.jpg)
Aliases
== >> ===
!= >> !==
is >> ===
isnt >> !==
13
![Page 20: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/20.jpg)
Aliases
on >> true
off >>false
yes >> true
no >> false
13
![Page 21: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/21.jpg)
Aliases
@property >> this.property
13
![Page 22: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/22.jpg)
and >> &&
not >> !
or >> ||
unless>> if !
Aliases
13
![Page 23: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/23.jpg)
Aliases
winner = yes if pick in [47, 92, 13]
render = yes if key of { a: 1, b: 2 }
13
![Page 24: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/24.jpg)
OOP
class Animal constructor: (@name) ->
move: (meters) -> alert @name + " moved " + meters + "m."
class Snake extends Animal move: -> alert "Slithering..." super 5
sam = new Snake "Sammy the Python"sam.move()
14
![Page 25: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/25.jpg)
OOPvar Animal, Snake, sam;var __extends = function(child, parent) { var ctor = function(){}; ctor.prototype = parent.prototype; child.prototype = new ctor(); child.prototype.constructor = child; if (typeof parent.extended === "function") parent.extended(child); child.__super__ = parent.prototype; };Animal = function(_arg) { this.name = _arg; return this;};Animal.prototype.move = function(meters) { return alert(this.name + " moved " + meters + "m.");};Snake = function() { return Animal.apply(this, arguments);};__extends(Snake, Animal);Snake.prototype.move = function() { alert("Slithering..."); return Snake.__super__.move.call(this, 5);};sam = new Snake("Sammy the Python");sam.move();
14
![Page 26: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/26.jpg)
Pattern Matching
theBait = 1000theSwitch = 0
[theBait, theSwitch] = [theSwitch, theBait]
weatherReport = (location) -> [location, 72, "Mostly Sunny"]
[zip, temp, forecast] = weatherReport "20175
15
![Page 27: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/27.jpg)
var _ref, forecast, temp, theBait, theSwitch, weatherReport, zip;theBait = 1000;theSwitch = 0;_ref = [theSwitch, theBait];theBait = _ref[0];theSwitch = _ref[1];
weatherReport = function(location) { return [location, 72, "Mostly Sunny"];};_ref = weatherReport("20175");zip = _ref[0];temp = _ref[1];forecast = _ref[2];
Pattern Matching
15
![Page 28: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/28.jpg)
Existential Operator
alert "I knew it!" if elvis?
speed ?= 140
root = exports ? this
lottery.drawWinner()?.address?.zipcode
16
![Page 29: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/29.jpg)
Existential Operator
var _ref, _ref2, root, speed;if (typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!");}
speed = (typeof speed !== "undefined" && speed !== null) ? speed : 140;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
(typeof (_ref2 = ((_ref = lottery.drawWinner()))) === "undefined" || _ref2 === null) ? undefined : _ref2.address == null ? undefined : _ref2.address.zipcode;
16
![Page 30: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/30.jpg)
String and RegExp Interpolation
quote = "A picture is a fact."author = "Wittgenstein"phrase = "#{quote} -- #{author}"
sentence = "#{ 22 / 7 } approximates π"
sep = "[.\\/\\- ]"dates = /\d+#{sep}\d+#{sep}\d+/g
17
![Page 31: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/31.jpg)
var author, dates, phrase, quote, sentence, sep;quote = "A picture is a fact.";author = "Wittgenstein";phrase = ("" + (quote) + " -- " + (author));
sentence = ("" + (22 / 7) + " is a decent approximation of π");
sep = "[.\\/\\- ]";dates = (new RegExp("\\d+" + (sep) + "\\d+" + (sep) + "\\d+", "g"));
String and RegExp Interpolation
17
![Page 32: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/32.jpg)
Splat Arguments
awardMedals = (first, second, others...) -> alert("Gold: #{first}"); alert("Silver: #{second}"); alert("The Field: #{others}");
18
![Page 33: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/33.jpg)
var awardMedals;var __slice = Array.prototype.slice;awardMedals = function(first, second) { var others; others = __slice.call(arguments, 2); alert("Gold: " + (first)); alert("Silver: " + (second)); return alert("The Field: " + (others));};
Splat Arguments
18
![Page 34: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/34.jpg)
foods = ['toast', 'cheese', 'wine']lunch = (eat(food) for food in foods)
yearsOld = max: 10, ida: 9, tim: 11ages = for child, age of yearsOld "#{child} is #{age}"
Array and Object Comprehensions
19
![Page 35: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/35.jpg)
var _i, _len, _ref, _result, age, ages, child, food, foods, lunch, yearsOld;var __hasProp = Object.prototype.hasOwnProperty;foods = ['toast', 'cheese', 'wine'];lunch = (function() { _result = []; _ref = foods; for (_i = 0, _len = _ref.length; _i < _len; _i++) { food = _ref[_i]; _result.push(eat(food)); } return _result;})();
yearsOld = { max: 10, ida: 9, tim: 11};ages = (function() { _result = []; _ref = yearsOld; for (child in _ref) { if (!__hasProp.call(_ref, child)) continue; age = _ref[child]; _result.push("" + (child) + " is " + (age)); } return _result;})();
Array and Object Comprehensions
19
![Page 36: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/36.jpg)
numbers = [0..9]
threeToSix = numbers[3..6]
copy = numbers[0...numbers.length]
numbers[3..6] = [-3, -4, -5, -6]
Slicing and Splicing
20
![Page 37: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/37.jpg)
var copy, numbers, threeToSix;numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
threeToSix = numbers.slice(3, 6 + 1);
copy = numbers.slice(0, numbers.length);
numbers.splice.apply(numbers, [3, 6 - 3 + 1].concat([-3, -4, -5, -6]));
Slicing and Splicing
20
![Page 38: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/38.jpg)
Function Binding
Account = (customer, cart) -> @customer = customer @cart = cart
$('#checkout').bind 'click', (event) => @customer.purchase @cart
21
![Page 39: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/39.jpg)
Function Binding
var Account;var __bind = function(func, context) { return function(){ return func.apply(context, arguments); }; };Account = function(customer, cart) { this.customer = customer; this.cart = cart; return $('#checkout').bind('click', __bind(function(event) { return this.customer.purchase(this.cart); }, this));};
21
![Page 40: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/40.jpg)
The Rest...
Everything is an expression; always a return valuePattern matching with object literalsSwitch/When/ElseWhile/Until/LoopTry/Catch/FinallyChained comparisonMultiline Strings, Heredocs, and Block Comments"text/coffeescript" script tags with extras/coffee-script.jsCake and Cakefiles
http://jashkenas.github.com/coffee-script/22
![Page 41: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/41.jpg)
Let’s Try It...
23
![Page 42: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/42.jpg)
Ideas for Getting Started
24
![Page 43: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/43.jpg)
Currently In Use
Making greatconferences even better
busyconf.com
25
![Page 44: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/44.jpg)
Ryan McGeary
http://ryan.mcgeary.org
@rmm5t
McGeary Consulting Group
26
![Page 45: CoffeeScript](https://reader034.vdocuments.us/reader034/viewer/2022042713/546c36aeaf7959b7028b6992/html5/thumbnails/45.jpg)
Attributionshttp://jashkenas.github.com/coffee-script/
http://www.flickr.com/photos/74234765@N00/488955057/
http://www.flickr.com/photos/adunne/3974874247/
http://www.flickr.com/photos/28111377@N07/2970550798/
http://www.flickr.com/photos/7678790@N06/3380560365/
http://www.flickr.com/photos/40775750@N00/531138641/
http://www.flickr.com/photos/86176561@N00/492795782/
http://www.flickr.com/photos/77555797@N00/133942287/
http://www.flickr.com/photos/34580986@N03/4985041197/
http://www.flickr.com/photos/83275741@N00/291831432/
http://www.flickr.com/photos/58115002@N00/3283033324/
http://www.flickr.com/photos/15133799@N02/3339157498/
http://www.flickr.com/photos/17731548@N00/981372736/
http://www.flickr.com/photos/7576193@N07/2476397335/
http://www.flickr.com/photos/48553010@N00/408767516/
http://www.free-computer-wallpapers.com/pictures/Television_wallpaper/Alias_2
http://www.flickr.com/photos/44742295@N00/3998772594/
http://www.flickr.com/photos/79659919@N00/3413379549/
http://www.flickr.com/photos/82402200@N00/523497824/
27