74
Why CoeeScript Is Awesome* *IMO @jocranford Tuesday, 8 May 12

Why (I think) CoffeeScript Is Awesome

Embed Size (px)

DESCRIPTION

Slides for a CoffeeScript presentation at Ruby on Rails Sydney user group on May 8.

Citation preview

Page 1: Why (I think) CoffeeScript Is Awesome

Why CoffeeScript IsAwesome*

*IMO@jocranfordTuesday, 8 May 12

Page 2: Why (I think) CoffeeScript Is Awesome

How CoffeeScript works

 

file.js webpage.htmlCompilefile.coffee

Include via <script>

Tuesday, 8 May 12

Page 3: Why (I think) CoffeeScript Is Awesome

Getting started was EASY

Tuesday, 8 May 12

Page 4: Why (I think) CoffeeScript Is Awesome

Installation with Node Package Manager

Tuesday, 8 May 12

Page 5: Why (I think) CoffeeScript Is Awesome

Compiling a Coffee Script File

Tuesday, 8 May 12

Page 6: Why (I think) CoffeeScript Is Awesome

Compiling Multiple Coffee Script Files

Tuesday, 8 May 12

Page 7: Why (I think) CoffeeScript Is Awesome

Web Workbench Visual Studio Plugin

Tuesday, 8 May 12

Page 8: Why (I think) CoffeeScript Is Awesome

Autogeneration of JavaScript

Tuesday, 8 May 12

Page 9: Why (I think) CoffeeScript Is Awesome

Errors in Output Window

Tuesday, 8 May 12

Page 10: Why (I think) CoffeeScript Is Awesome

Basic Syntax

Tuesday, 8 May 12

Page 11: Why (I think) CoffeeScript Is Awesome

var myPresentation = { title: "CoffeeScript", when: { day: "8 May 2012", time: "6:30pm" }};

Object Definition

Tuesday, 8 May 12

Page 12: Why (I think) CoffeeScript Is Awesome

var myPresentation = { title: "CoffeeScript", when: { day: "8 May 2012", time: "6:30pm" }};

Object Definition

myPresentation = subject: "CoffeeScript” when: day: "8 May 2012" time: "6:30pm"

Tuesday, 8 May 12

Page 13: Why (I think) CoffeeScript Is Awesome

var myPresentation = { title: "CoffeeScript", when: { day: "8 May 2012", time: "6:30pm" }};

Object Definition

myPresentation = subject: "CoffeeScript” when: day: "8 May 2012" time: "6:30pm"

Tuesday, 8 May 12

Page 14: Why (I think) CoffeeScript Is Awesome

Function Definitionfunction startPresentation(subject) { alert("A presentation about " + subject + " is now starting!");}

var startPresentation = function(subject) { alert("A presentation about " + subject + " is now starting!");};

startPresentation("JavaScript");

Tuesday, 8 May 12

Page 15: Why (I think) CoffeeScript Is Awesome

Function Definitionfunction startPresentation(subject) { alert("A presentation about " + subject + " is now starting!");}

var startPresentation = function(subject) { alert("A presentation about " + subject + " is now starting!");};

startPresentation("JavaScript");

startPresentation = (subject) -> alert "A presentation about " + subject + " is now starting!"

startPresentation "CoffeeScript"

Tuesday, 8 May 12

Page 16: Why (I think) CoffeeScript Is Awesome

Function Definitionfunction startPresentation(subject) { alert("A presentation about " + subject + " is now starting!");}

var startPresentation = function(subject) { alert("A presentation about " + subject + " is now starting!");};

startPresentation("JavaScript");

startPresentation = (subject) -> alert "A presentation about " + subject + " is now starting!"

startPresentation "CoffeeScript"

Tuesday, 8 May 12

Page 17: Why (I think) CoffeeScript Is Awesome

Operators

CoffeeScript JavaScript

is ===

isnt !==

not !

and &&

or ||

of in

Tuesday, 8 May 12

Page 18: Why (I think) CoffeeScript Is Awesome

Syntactic Sugar

Tuesday, 8 May 12

Page 19: Why (I think) CoffeeScript Is Awesome

String Interpolation

var description = "This is a talk about " + myPresentation.subject + " by " + myPresentation.presenter + ". It will start at " + myPresentation.startTime + " and finish by " + myPresentation.endTime;

Tuesday, 8 May 12

Page 20: Why (I think) CoffeeScript Is Awesome

String Interpolation

var description = "This is a talk about " + myPresentation.subject + " by " + myPresentation.presenter + ". It will start at " + myPresentation.startTime + " and finish by " + myPresentation.endTime;

description = "This is a talk about #{myPresentation.subject} by #{myPresentation.presenter}. It will start at #{myPresentation.startTime} and finish by #{myPresentation.endTime}"

Tuesday, 8 May 12

Page 21: Why (I think) CoffeeScript Is Awesome

String Interpolation

var description = "This is a talk about " + myPresentation.subject + " by " + myPresentation.presenter + ". It will start at " + myPresentation.startTime + " and finish by " + myPresentation.endTime;

description = "This is a talk about #{myPresentation.subject} by #{myPresentation.presenter}. It will start at #{myPresentation.startTime} and finish by #{myPresentation.endTime}"

Tuesday, 8 May 12

Page 22: Why (I think) CoffeeScript Is Awesome

@ replaces thisvar Presentation = function(title, presenter) {

this.getHeadline = function() { return title + " by " + presenter; };

this.showHeadline = function() { alert(this.getHeadline()); };

};

Tuesday, 8 May 12

Page 23: Why (I think) CoffeeScript Is Awesome

@ replaces this

class Presentation

constructor: (@title, @presenter) ->

getHeadline: -> "#{@title} by #{@presenter}"

showHeadline: -> alert(@getHeadline())

var Presentation = function(title, presenter) {

this.getHeadline = function() { return title + " by " + presenter; };

this.showHeadline = function() { alert(this.getHeadline()); };

};

Tuesday, 8 May 12

Page 24: Why (I think) CoffeeScript Is Awesome

@ replaces this

class Presentation

constructor: (@title, @presenter) ->

getHeadline: -> "#{@title} by #{@presenter}"

showHeadline: -> alert(@getHeadline())

var Presentation = function(title, presenter) {

this.getHeadline = function() { return title + " by " + presenter; };

this.showHeadline = function() { alert(this.getHeadline()); };

};

Tuesday, 8 May 12

Page 25: Why (I think) CoffeeScript Is Awesome

functions return the last value

function add(x, y) { return x + y;}

Tuesday, 8 May 12

Page 26: Why (I think) CoffeeScript Is Awesome

functions return the last value

function add(x, y) { return x + y;}

add = (x, y) -> x + y

Tuesday, 8 May 12

Page 27: Why (I think) CoffeeScript Is Awesome

functions return the last value

function add(x, y) { return x + y;}

add = (x, y) -> x + y

Tuesday, 8 May 12

Page 28: Why (I think) CoffeeScript Is Awesome

Conditionals return automaticallyvar textColor;

if (result === "failed") { textColor = "red";} else if (result === "not run") { textColor = "yellow";} else { textColor = "green";}

Tuesday, 8 May 12

Page 29: Why (I think) CoffeeScript Is Awesome

Conditionals return automaticallyvar textColor;

if (result === "failed") { textColor = "red";} else if (result === "not run") { textColor = "yellow";} else { textColor = "green";}

textColor = if result is "failed" "red" else if result is "not run" "yellow" else "green"

Tuesday, 8 May 12

Page 30: Why (I think) CoffeeScript Is Awesome

Conditionals return automaticallyvar textColor;

if (result === "failed") { textColor = "red";} else if (result === "not run") { textColor = "yellow";} else { textColor = "green";}

textColor = if result is "failed" "red" else if result is "not run" "yellow" else "green"

Tuesday, 8 May 12

Page 31: Why (I think) CoffeeScript Is Awesome

Protection from Evil

Tuesday, 8 May 12

Page 32: Why (I think) CoffeeScript Is Awesome

In JavaScript, variables are global by default

var tonightsPresentations = [ "CoffeeScript", "i18n", "Rails Conf"];

var whoopsie = function() { tonightsPresentations = []; return tonightsPresentations;}

Tuesday, 8 May 12

Page 33: Why (I think) CoffeeScript Is Awesome

In CoffeeScript, they are automatically scoped

tonightsPresentations = [ "CoffeeScript", "i18n", "Rails Conf"]

whoopsie = ->! tonightsPresentations = []! tonightsPresentations

var tonightsPresentations = [ "CoffeeScript", "i18n", "Rails Conf"];

var whoopsie = function() { teamHugPresentationList = []; return teamHugPresentationList;}

Tuesday, 8 May 12

Page 34: Why (I think) CoffeeScript Is Awesome

WTF ...

0 == "" and 0 =="0" are both TRUE ... but "" == "0" is NOT!

false == "0" is TRUE ... but false == "false" is NOT!

Tuesday, 8 May 12

Page 35: Why (I think) CoffeeScript Is Awesome

WTF ...

0 == "" and 0 =="0" are both TRUE ... but "" == "0" is NOT!

false == "0" is TRUE ... but false == "false" is NOT!

is => ===

isnt => !==

== -> ===

Tuesday, 8 May 12

Page 36: Why (I think) CoffeeScript Is Awesome

With

;Reserved Keywords

Tuesday, 8 May 12

Page 37: Why (I think) CoffeeScript Is Awesome

Consistency

Tuesday, 8 May 12

Page 38: Why (I think) CoffeeScript Is Awesome

var Presentation = function(title, presenter) { return { getHeadline: function() { return title + " by " + presenter; } }};

var myPresentation = Presentation("CoffeeScript", "Jo Cranford");

Example 1

Tuesday, 8 May 12

Page 39: Why (I think) CoffeeScript Is Awesome

var Presentation = function(title, presenter) {

this.getHeadline = function() { return title + " by " + presenter; };

};

var myPresentation = new Presentation("CoffeeScript", "Jo Cranford");

Example 2

Tuesday, 8 May 12

Page 40: Why (I think) CoffeeScript Is Awesome

var Presentation = function(title, presenter) { this.title = title; this.presenter = presenter;};

Presentation.prototype.getHeadline = function() { return this.title + " by " + this.presenter;};

var myPresentation = new Presentation("CoffeeScript", "Jo Cranford");

Example 3

Tuesday, 8 May 12

Page 41: Why (I think) CoffeeScript Is Awesome

CoffeeScript

class Presentation

constructor: (@title, @presenter) ->

getHeadline: -> @title + " " + @presenter

Tuesday, 8 May 12

Page 42: Why (I think) CoffeeScript Is Awesome

Less Code

Tuesday, 8 May 12

Page 43: Why (I think) CoffeeScript Is Awesome

Average Lines Of Code

0

10

20

30

40

JavaScript CoffeeScript

1.8X

Tuesday, 8 May 12

Page 44: Why (I think) CoffeeScript Is Awesome

For Loopvar i, weatherInCities;

weatherInCities = [];

for(i = 0; i < listOfCities.length; i++) {

! var city = listOfCities[i];

! weatherInCities.push(city.name + ":" + city.weather);

}

Tuesday, 8 May 12

Page 45: Why (I think) CoffeeScript Is Awesome

For Loopvar i, weatherInCities;

weatherInCities = [];

for(i = 0; i < listOfCities.length; i++) {

! var city = listOfCities[i];

! weatherInCities.push(city.name + ":" + city.weather);

}

weatherInCities = (("#{city.name}: #{city.weather}") for city in listOfCities)

Tuesday, 8 May 12

Page 46: Why (I think) CoffeeScript Is Awesome

For Loopvar i, weatherInCities;

weatherInCities = [];

for(i = 0; i < listOfCities.length; i++) {

! var city = listOfCities[i];

! weatherInCities.push(city.name + ":" + city.weather);

}

weatherInCities = (("#{city.name}: #{city.weather}") for city in listOfCities)

Tuesday, 8 May 12

Page 47: Why (I think) CoffeeScript Is Awesome

var objectToString = function (obj) {! var key, val, _results;! _results = [];

! for (key in obj) {! ! if (!obj.hasOwnProperty(key)) continue;! ! val = obj[key];! ! if (val !== null) _results.push(key + ":" + val);! }! return _results.join(",");};

For “Own” Loop

Tuesday, 8 May 12

Page 48: Why (I think) CoffeeScript Is Awesome

var objectToString = function (obj) {! var key, val, _results;! _results = [];

! for (key in obj) {! ! if (!obj.hasOwnProperty(key)) continue;! ! val = obj[key];! ! if (val !== null) _results.push(key + ":" + val);! }! return _results.join(",");};

For “Own” Loop

objectToString = (obj) ->

! ("#{key}:#{val}" for own key, val of obj when val isnt null).join(“,")

Tuesday, 8 May 12

Page 49: Why (I think) CoffeeScript Is Awesome

var objectToString = function (obj) {! var key, val, _results;! _results = [];

! for (key in obj) {! ! if (!obj.hasOwnProperty(key)) continue;! ! val = obj[key];! ! if (val !== null) _results.push(key + ":" + val);! }! return _results.join(",");};

For “Own” Loop

objectToString = (obj) ->

! ("#{key}:#{val}" for own key, val of obj when val isnt null).join(“,")

Tuesday, 8 May 12

Page 50: Why (I think) CoffeeScript Is Awesome

var Region = function(states) {! this.states = states;};

Region.prototype.findStatesBeginningWith = function(letter) {! var matchingStates = []; for (var i = 0;i < this.states.length; i++) {! ! state = this.states[i];! ! if (state.substr(0,1) === letter) {! ! ! matchingStates.push(state)! ! }! }! return matchingStates;};

Constructor - JavaScript

Tuesday, 8 May 12

Page 51: Why (I think) CoffeeScript Is Awesome

class Region

constructor: (@states) ->

findStatesBeginningWith: (letter) ->

state for state in @states when state.substr(0,1) is letter

Constructor - CoffeeScript

Tuesday, 8 May 12

Page 52: Why (I think) CoffeeScript Is Awesome

class Region

constructor: (@states) ->

findStatesBeginningWith: (letter) ->

state for state in @states when state.substr(0,1) is letter

Constructor - CoffeeScript

Tuesday, 8 May 12

Page 53: Why (I think) CoffeeScript Is Awesome

var Clickable = function (baseElement) {

! var that = this;

! this.displayAlert = function() {

! ! alert("You just clicked me!");

! };

! $(baseElement).click(that.displayAlert);

};

this and that

Tuesday, 8 May 12

Page 54: Why (I think) CoffeeScript Is Awesome

var Clickable = function (baseElement) {

! var that = this;

! this.displayAlert = function() {

! ! alert("You just clicked me!");

! };

! $(baseElement).click(that.displayAlert);

};

this and that

Tuesday, 8 May 12

Page 55: Why (I think) CoffeeScript Is Awesome

var Clickable = function (baseElement) {

! var that = this;

! this.displayAlert = function() {

! ! alert("You just clicked me!");

! };

! $(baseElement).click(that.displayAlert);

};

this and that

class window.Clickable

constructor: (@baseElement) ->

$(@baseElement).click(@displayAlert)

displayAlert: =>

window.alert("You just clicked me!")

Tuesday, 8 May 12

Page 56: Why (I think) CoffeeScript Is Awesome

var Clickable = function (baseElement) {

! var that = this;

! this.displayAlert = function() {

! ! alert("You just clicked me!");

! };

! $(baseElement).click(that.displayAlert);

};

this and that

class window.Clickable

constructor: (@baseElement) ->

$(@baseElement).click(@displayAlert)

displayAlert: =>

window.alert("You just clicked me!")

Tuesday, 8 May 12

Page 57: Why (I think) CoffeeScript Is Awesome

Pattern Matching – Reading an Object

var london = { lat: 51.5171, lng: 0.1062};

var lat = london.lat;var lng = london.lng;

Tuesday, 8 May 12

Page 58: Why (I think) CoffeeScript Is Awesome

Pattern Matching – Reading an Object

var london = { lat: 51.5171, lng: 0.1062};

var lat = london.lat;var lng = london.lng;

london = lat: 51.5171 lng: 0.1062

{lat,lng} = london

Tuesday, 8 May 12

Page 59: Why (I think) CoffeeScript Is Awesome

Pattern Matching

var london = { lat: 51.5171, lng: 0.1062};

var lat = london.lat;var lng = london.lng;

london = lat: 51.5171 lng: 0.1062

{lat,lng} = london

Tuesday, 8 May 12

Page 60: Why (I think) CoffeeScript Is Awesome

Pattern Matching

doSomethingWithPoint = ({lat,lng}) -> console.log(lat, lng);

doSomethingWithPoint london

createPoint = (lat, lng) -> { lat, lng }

Tuesday, 8 May 12

Page 61: Why (I think) CoffeeScript Is Awesome

Existing libraries just work

Tuesday, 8 May 12

Page 62: Why (I think) CoffeeScript Is Awesome

JQuery$(document).ready(function() { var tip = $("#js-tooltip");

if (!tip.hasClass("hidden")) { tip.addClass("hidden"); }});

Tuesday, 8 May 12

Page 63: Why (I think) CoffeeScript Is Awesome

$(document).ready(function() { var tip = $("#js-tooltip");

if (!tip.hasClass("hidden")) { tip.addClass("hidden"); }});

JQuery

$(document).ready(-> tip = $ "#coffee-tooltip"

tip.addClass "hidden" unless tip.hasClass "hidden")

Tuesday, 8 May 12

Page 64: Why (I think) CoffeeScript Is Awesome

$(document).ready(function() { var tip = $("#js-tooltip");

if (!tip.hasClass("hidden")) { tip.addClass("hidden"); }});

JQuery

$(document).ready(-> tip = $ "#coffee-tooltip"

tip.addClass "hidden" unless tip.hasClass "hidden")

Tuesday, 8 May 12

Page 65: Why (I think) CoffeeScript Is Awesome

Easy to Test with Jasmine

Tuesday, 8 May 12

Page 66: Why (I think) CoffeeScript Is Awesome

describe("The Game Object", function() {

it("should have a score of 0 if I knock down no skittles", function() { var game = new Game(); game.roll(0); var score = game.score(); expect(score).toBe(0); });});

Jasmine Test

Tuesday, 8 May 12

Page 67: Why (I think) CoffeeScript Is Awesome

describe("The Game Object", function() {

it("should have a score of 0 if I knock down no skittles", function() { var game = new Game(); game.roll(0); var score = game.score(); expect(score).toBe(0); });});

describe "The Game Object", ->

it "should have a score of 0 if I knock down no skittles", -> game = new Game() game.roll(0) score = game.score() expect(score).toBe 0

Jasmine Test

Tuesday, 8 May 12

Page 68: Why (I think) CoffeeScript Is Awesome

Clean, Efficient, Easy to Read JavaScript

Tuesday, 8 May 12

Page 69: Why (I think) CoffeeScript Is Awesome

class Presentation

constructor: (@title, @presenter) ->

getHeadline: -> "#{@title} #{@presenter}"

Tuesday, 8 May 12

Page 70: Why (I think) CoffeeScript Is Awesome

(function() { var Presentation;

Presentation = (function() {

Presentation.name = 'Presentation';

function Presentation(title, presenter) { this.title = title; this.presenter = presenter; }

Presentation.prototype.getHeadline = function() { return this.title + " " + this.presenter; };

return Presentation;

})();

}).call(this);

Tuesday, 8 May 12

Page 71: Why (I think) CoffeeScript Is Awesome

(function() { var Presentation;

Presentation = (function() {

Presentation.name = 'Presentation';

function Presentation(title, presenter) { this.title = title; this.presenter = presenter; }

Presentation.prototype.getHeadline = function() { return this.title + " " + this.presenter; };

return Presentation;

})();

}).call(this);

Tuesday, 8 May 12

Page 72: Why (I think) CoffeeScript Is Awesome

Of course, it’s not perfect

Tuesday, 8 May 12

Page 73: Why (I think) CoffeeScript Is Awesome

It IS an additional step

Debugging

Shouldn't we just write good JavaScript?

Should we even be writing object oriented JavaScript?

Tuesday, 8 May 12

Page 74: Why (I think) CoffeeScript Is Awesome

References

• http://coffeescript.org/• http://www.weave.de/wp-content/uploads/2012/01/The-Little-Book-on-

Coffee-Script.pdf• http://pragprog.com/magazines/2011-05/a-coffeescript-intervention• http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/• http://css.dzone.com/articles/source-maps-coffeescript• http://www.quora.com/CoffeeScript/What-are-disadvantages-of-using-

CoffeeScript• http://www.readwriteweb.com/hack/2011/01/interview-coffeescript-jeremy-

ashkenas.php• http://rzrsharp.net/2011/06/27/what-does-coffeescripts-do-do.html• http://stackoverflow.com/questions/643542/doesnt-javascript-support-

closures-with-local-variables/643664#643664• http://yannesposito.com/Scratch/en/blog/2011-01-03-Why-I-sadly-won-t-

use-coffeescript/

Tuesday, 8 May 12