coffeescript and you
 become a better javascript developer
what coffeescript
     is not
not just a lack of
 punctuation!
so what is
coffeescript?
coffeescript is...
coffeescript is...
“a little language that compiles into
JavaScript”
easier to read and write
a hybrid of ruby and python
helpful
haven’t i heard this
     before?
other js compilers
other js compilers

gwt (java)
jsil (.net)
pyjamas (python)
gwt
import     com.google.gwt.core.client.EntryPoint;
import     com.google.gwt.user.client.Window;
import     com.google.gwt.user.client.ui.Button;
import     com.google.gwt.user.client.ui.ClickListener;
import     com.google.gwt.user.client.ui.RootPanel;
import     com.google.gwt.user.client.ui.Widget;

/**
 * HelloWorld application.
 */
public class Hello implements EntryPoint {

    public void onModuleLoad() {
      Button b = new Button("Click me", new ClickListener() {
        public void onClick(Widget sender) {
          Window.alert("Hello World");
        }
      });

        RootPanel.get().add(b);
    }
}
jsil
using System;
using System.Collections.Generic;

public static class Program {
    public static void Main (string[] args) {
        var array = new[] { 1, 2, 4, 8, 16 };

        foreach (var i in array)
            Console.WriteLine(i);

        var list = new List<int>(array);

        foreach (var j in list)
            Console.WriteLine(j);
    }
}
pyjamas
from pyjamas import Window
from pyjamas.ui import RootPanel, Button

def greet(sender):
    Window.alert("Hello, AJAX!")

b = Button("Click me", greet)
RootPanel().add(b)
so why should i
embrace (and love)
  coffeescript?
example
$(function() {
   $.get('example.php', function(data) {
      if (data.errors != null) {
        alert("There was an error!");
      } else {
        $("#content").text(data.message);
      }
   })
})
$(function() {
   $.get('example.php', function(data) {
      if (data.errors != null) {
        alert("There was an error!")
      } else {
        $("#content").text(data.message)
      }
   })
})
$ function() {
  $.get 'example.php', function(data) {
    if data.errors != null {
      alert "There was an error!"
    } else {
      $("#content").text data.message
    }
  }
}
$ function()
  $.get 'example.php', function(data)
    if data.errors != null
      alert "There was an error!"
    else
      $("#content").text data.message
$ ()->
  $.get 'example.php', (data)->
    if data.errors != null
       alert "There was an error!"
    else
       $("#content").text data.message
$ ->
  $.get 'example.php', (data)->
     if data.errors?
       alert "There was an error!"
     else
       $("#content").text data.message
$(function() {
   $.get('example.php', function(data) {
      if (data.errors != null) {
        alert("There was an error!");
      } else {
        $("#content").text(data.message);
      }
   })
})
ranges
# 1, 2, 3, 4, 5
[1..5]

# 1,..., 4
[1...5]

#1,...,500
[1..500]

#5, 4, 3, 2, 1
[5..1]

#500,...,1
[500..1]
var _i, _j, _results, _results2;
[1, 2, 3, 4, 5];
[1, 2, 3, 4];
(function() {
  _results = [];
  for (_i = 1; _i <= 500; _i++)
{ _results.push(_i); }
  return _results;
}).apply(this, arguments);
[5, 4, 3, 2, 1];
(function() {
  _results2 = [];
  for (_j = 500; _j >= 1; _j--)
{ _results2.push(_j); }
  return _results2;
}).apply(this, arguments);
conditionals
if a
  console.log "a is true"
else
  console.log "a is false"

unless a
  console.log "a is false"

console.log "a is false" unless a
if (a) {
  console.log("a   is true");
} else {
  console.log("a   is false");
}
if (!a) {
  console.log("a   is false");
}
if (!a) {
  console.log("a   is false");
}
if a is 'A'
  console.log "a is A"

if a == 'A'
  console.log "a is A"
if (a === 'A') {
  console.log("a is A");
}
if (a === 'A') {
  console.log("a is A");
}
existential operator
console?.log "Only log if there is a
console"

if $("#bid_form")?.html()? and @model?
  doSomething()
var _ref;
if (typeof console !== "undefined" && console !== null) {
  console.log("Only log if there is a console");
}
if ((((_ref = $("#bid_form")) != null ? _ref.html() : void
0) != null) && (this.model != null)) {
  doSomething();
}
functions
sayHi = (name)->
  console.log "hello: #{name}"

sayHi 'mark'
sayHi('mark')

sayBye = ->
  console.log "bye!"

sayBye()
var sayBye, sayHi;
sayHi = function(name) {
   return console.log("hello: " + name);
};
sayHi('mark');
sayHi('mark');
sayBye = function() {
   return console.log("bye!");
};
sayBye();
bound functions
class User

  constructor: (@name) ->

  sayHi: ->
    console.log "Hello, #{@name}"

u1 = new User('mark')
u2 = new User('bob')

jqxhr = $.get "example.php", ->
    alert "success"

jqxhr.success u1.sayHi
jqxhr.success u2.sayHi
var User, jqxhr, u1, u2;
User = (function() {
  function User(name) {
     this.name = name;
  }
  User.prototype.sayHi = function() {
     return console.log("Hello, " + this.name);
  };
  return User;
})();
u1 = new User('mark');
u2 = new User('bob');
jqxhr = $.get("example.php", function() {
  return alert("success");
});
jqxhr.success(u1.sayHi);
jqxhr.success(u2.sayHi);
Hello, undefined
Hello, undefined
class User

  constructor: (@name) ->

  sayHi: ->
    console.log "Hello, #{@name}"

u1 = new User('mark')
u2 = new User('bob')

jqxhr = $.get "example.php", ->
    alert "success"

jqxhr.success u1.sayHi
jqxhr.success u2.sayHi
class User

  constructor: (@name) ->

  sayHi: =>
    console.log "Hello, #{@name}"

u1 = new User('mark')
u2 = new User('bob')

jqxhr = $.get "example.php", ->
    alert "success"

jqxhr.success u1.sayHi
jqxhr.success u2.sayHi
var User, jqxhr, u1, u2;
var __bind = function(fn, me){ return function(){ return
fn.apply(me, arguments); }; };
User = (function() {
  function User(name) {
     this.name = name;
     this.sayHi = __bind(this.sayHi, this);
  }
  User.prototype.sayHi = function() {
     return console.log("Hello, " + this.name);
  };
  return User;
})();
u1 = new User('mark');
u2 = new User('bob');
jqxhr = $.get("example.php", function() {
  return alert("success");
});
jqxhr.success(u1.sayHi);
jqxhr.success(u2.sayHi);
Hello, mark
Hello, bob
default arguments
createElement = (name, attributes = {}) ->
  obj = document.createElement name
  for key, val of attributes
    obj.setAttribute key, val
  obj
var createElement;
createElement = function(name, attributes) {
   var key, obj, val;
   if (attributes == null) {
     attributes = {};
   }
   obj = document.createElement(name);
   for (key in attributes) {
     val = attributes[key];
     obj.setAttribute(key, val);
   }
   return obj;
};
scope
a = 'A'
myFunc = ->
  a = 'AAA'
  b = 'B'
(function() {
  var a, myFunc;
  a = 'A';
  myFunc = function() {
     var b;
     a = 'AAA';
     return b = 'B';
  };
}).call(this);
array loops
arr = [1..5]

for num in arr
  console.log num
var arr, num, _i, _len;
arr = [1, 2, 3, 4, 5];
for (_i = 0, _len = arr.length; _i < _len; _i++) {
  num = arr[_i];
  console.log(num);
}
classes

easy to define
easy to extend
help keep code clean
class Employee

  constructor: (@name, @options = {})->

  job: ->
    @options.job

mark = new Employee('Mark', job: 'Developer')

mark.job() # => 'Developer'
mark.name # => 'Mark'
var Employee, mark;
Employee = (function() {
  function Employee(name, options) {
     this.name = name;
     this.options = options != null ? options : {};
  }
  Employee.prototype.job = function() {
     return this.options.job;
  };
  return Employee;
})();
mark = new Employee('Mark', {
  job: 'Developer'
});
mark.job();
mark.name;
extending classes
class Manager extends Employee

  job: ->
    "$$$ #{super}"

steve = new Manager('Steve', job: 'CEO')

steve.job() # => '$$$ CEO'
steve.name # => 'Steve'
var Manager, steve;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
   for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
   function ctor() { this.constructor = child; }
   ctor.prototype = parent.prototype;
   child.prototype = new ctor;
   child.__super__ = parent.prototype;
   return child;
};
Manager = (function() {
   __extends(Manager, Employee);
   function Manager() {
      Manager.__super__.constructor.apply(this, arguments);
   }
   Manager.prototype.job = function() {
      return "$$$ " + Manager.__super__.job.apply(this, arguments);
   };
   return Manager;
})();
steve = new Manager('Steve', {
   job: 'CEO'
});
steve.job();
steve.name;
what the hell is @?
class User

  constructor: (@name)->
    @new_record = true

  @find: (id)->
    # do some work
class User

  constructor: (name)->
    @name = name
    @new_record = true

  @find: (id)->
    # do some work
var User;
User = (function() {
  function User(name) {
    this.name = name;
    this.new_record = true;
  }
  User.find = function(id) {};
  return User;
})();
thank you
                   @markbates
           http://www.markbates.com
http://www.slideshare.net/markykang/coffeescript-and-you

CoffeeScript and You

  • 1.
    coffeescript and you become a better javascript developer
  • 2.
  • 3.
    not just alack of punctuation!
  • 4.
  • 5.
  • 6.
    coffeescript is... “a littlelanguage that compiles into JavaScript” easier to read and write a hybrid of ruby and python helpful
  • 7.
    haven’t i heardthis before?
  • 8.
  • 9.
    other js compilers gwt(java) jsil (.net) pyjamas (python)
  • 10.
    gwt import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; /** * HelloWorld application. */ public class Hello implements EntryPoint { public void onModuleLoad() { Button b = new Button("Click me", new ClickListener() { public void onClick(Widget sender) { Window.alert("Hello World"); } }); RootPanel.get().add(b); } }
  • 11.
    jsil using System; using System.Collections.Generic; publicstatic class Program { public static void Main (string[] args) { var array = new[] { 1, 2, 4, 8, 16 }; foreach (var i in array) Console.WriteLine(i); var list = new List<int>(array); foreach (var j in list) Console.WriteLine(j); } }
  • 12.
    pyjamas from pyjamas importWindow from pyjamas.ui import RootPanel, Button def greet(sender): Window.alert("Hello, AJAX!") b = Button("Click me", greet) RootPanel().add(b)
  • 13.
    so why shouldi embrace (and love) coffeescript?
  • 14.
  • 15.
    $(function() { $.get('example.php', function(data) { if (data.errors != null) { alert("There was an error!"); } else { $("#content").text(data.message); } }) })
  • 16.
    $(function() { $.get('example.php', function(data) { if (data.errors != null) { alert("There was an error!") } else { $("#content").text(data.message) } }) })
  • 17.
    $ function() { $.get 'example.php', function(data) { if data.errors != null { alert "There was an error!" } else { $("#content").text data.message } } }
  • 18.
    $ function() $.get 'example.php', function(data) if data.errors != null alert "There was an error!" else $("#content").text data.message
  • 19.
    $ ()-> $.get 'example.php', (data)-> if data.errors != null alert "There was an error!" else $("#content").text data.message
  • 20.
    $ -> $.get 'example.php', (data)-> if data.errors? alert "There was an error!" else $("#content").text data.message
  • 21.
    $(function() { $.get('example.php', function(data) { if (data.errors != null) { alert("There was an error!"); } else { $("#content").text(data.message); } }) })
  • 22.
  • 23.
    # 1, 2,3, 4, 5 [1..5] # 1,..., 4 [1...5] #1,...,500 [1..500] #5, 4, 3, 2, 1 [5..1] #500,...,1 [500..1]
  • 24.
    var _i, _j,_results, _results2; [1, 2, 3, 4, 5]; [1, 2, 3, 4]; (function() { _results = []; for (_i = 1; _i <= 500; _i++) { _results.push(_i); } return _results; }).apply(this, arguments); [5, 4, 3, 2, 1]; (function() { _results2 = []; for (_j = 500; _j >= 1; _j--) { _results2.push(_j); } return _results2; }).apply(this, arguments);
  • 25.
  • 26.
    if a console.log "a is true" else console.log "a is false" unless a console.log "a is false" console.log "a is false" unless a
  • 27.
    if (a) { console.log("a is true"); } else { console.log("a is false"); } if (!a) { console.log("a is false"); } if (!a) { console.log("a is false"); }
  • 28.
    if a is'A' console.log "a is A" if a == 'A' console.log "a is A"
  • 29.
    if (a ==='A') { console.log("a is A"); } if (a === 'A') { console.log("a is A"); }
  • 30.
  • 31.
    console?.log "Only logif there is a console" if $("#bid_form")?.html()? and @model? doSomething()
  • 32.
    var _ref; if (typeofconsole !== "undefined" && console !== null) { console.log("Only log if there is a console"); } if ((((_ref = $("#bid_form")) != null ? _ref.html() : void 0) != null) && (this.model != null)) { doSomething(); }
  • 33.
  • 34.
    sayHi = (name)-> console.log "hello: #{name}" sayHi 'mark' sayHi('mark') sayBye = -> console.log "bye!" sayBye()
  • 35.
    var sayBye, sayHi; sayHi= function(name) { return console.log("hello: " + name); }; sayHi('mark'); sayHi('mark'); sayBye = function() { return console.log("bye!"); }; sayBye();
  • 36.
  • 37.
    class User constructor: (@name) -> sayHi: -> console.log "Hello, #{@name}" u1 = new User('mark') u2 = new User('bob') jqxhr = $.get "example.php", -> alert "success" jqxhr.success u1.sayHi jqxhr.success u2.sayHi
  • 38.
    var User, jqxhr,u1, u2; User = (function() { function User(name) { this.name = name; } User.prototype.sayHi = function() { return console.log("Hello, " + this.name); }; return User; })(); u1 = new User('mark'); u2 = new User('bob'); jqxhr = $.get("example.php", function() { return alert("success"); }); jqxhr.success(u1.sayHi); jqxhr.success(u2.sayHi);
  • 39.
  • 40.
    class User constructor: (@name) -> sayHi: -> console.log "Hello, #{@name}" u1 = new User('mark') u2 = new User('bob') jqxhr = $.get "example.php", -> alert "success" jqxhr.success u1.sayHi jqxhr.success u2.sayHi
  • 41.
    class User constructor: (@name) -> sayHi: => console.log "Hello, #{@name}" u1 = new User('mark') u2 = new User('bob') jqxhr = $.get "example.php", -> alert "success" jqxhr.success u1.sayHi jqxhr.success u2.sayHi
  • 42.
    var User, jqxhr,u1, u2; var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; User = (function() { function User(name) { this.name = name; this.sayHi = __bind(this.sayHi, this); } User.prototype.sayHi = function() { return console.log("Hello, " + this.name); }; return User; })(); u1 = new User('mark'); u2 = new User('bob'); jqxhr = $.get("example.php", function() { return alert("success"); }); jqxhr.success(u1.sayHi); jqxhr.success(u2.sayHi);
  • 43.
  • 44.
  • 45.
    createElement = (name,attributes = {}) -> obj = document.createElement name for key, val of attributes obj.setAttribute key, val obj
  • 46.
    var createElement; createElement =function(name, attributes) { var key, obj, val; if (attributes == null) { attributes = {}; } obj = document.createElement(name); for (key in attributes) { val = attributes[key]; obj.setAttribute(key, val); } return obj; };
  • 47.
  • 48.
    a = 'A' myFunc= -> a = 'AAA' b = 'B'
  • 49.
    (function() { var a, myFunc; a = 'A'; myFunc = function() { var b; a = 'AAA'; return b = 'B'; }; }).call(this);
  • 50.
  • 51.
    arr = [1..5] fornum in arr console.log num
  • 52.
    var arr, num,_i, _len; arr = [1, 2, 3, 4, 5]; for (_i = 0, _len = arr.length; _i < _len; _i++) { num = arr[_i]; console.log(num); }
  • 53.
    classes easy to define easyto extend help keep code clean
  • 54.
    class Employee constructor: (@name, @options = {})-> job: -> @options.job mark = new Employee('Mark', job: 'Developer') mark.job() # => 'Developer' mark.name # => 'Mark'
  • 55.
    var Employee, mark; Employee= (function() { function Employee(name, options) { this.name = name; this.options = options != null ? options : {}; } Employee.prototype.job = function() { return this.options.job; }; return Employee; })(); mark = new Employee('Mark', { job: 'Developer' }); mark.job(); mark.name;
  • 56.
  • 57.
    class Manager extendsEmployee job: -> "$$$ #{super}" steve = new Manager('Steve', job: 'CEO') steve.job() # => '$$$ CEO' steve.name # => 'Steve'
  • 58.
    var Manager, steve; var__hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; Manager = (function() { __extends(Manager, Employee); function Manager() { Manager.__super__.constructor.apply(this, arguments); } Manager.prototype.job = function() { return "$$$ " + Manager.__super__.job.apply(this, arguments); }; return Manager; })(); steve = new Manager('Steve', { job: 'CEO' }); steve.job(); steve.name;
  • 59.
  • 60.
    class User constructor: (@name)-> @new_record = true @find: (id)-> # do some work
  • 61.
    class User constructor: (name)-> @name = name @new_record = true @find: (id)-> # do some work
  • 62.
    var User; User =(function() { function User(name) { this.name = name; this.new_record = true; } User.find = function(id) {}; return User; })();
  • 63.
    thank you @markbates http://www.markbates.com http://www.slideshare.net/markykang/coffeescript-and-you