CoffeeScript

Posted on 06 Jan 2010. in links javascript

CoffeeScript is a neat language that compiles down to JavaScript. The best part is that (unlike another language I’m thinking of) the resulting code is easily usable from normal JavaScript. It’s really just a layer of syntactic sugar on top of the base language.

However, there are some major differences:

  • : can optionally be used for assignment, instead of =. On one hand this is nice, as it unifies JSON syntax and normal language syntax. On the other, it feels really, really weird, and makes it harder to see when you’re looking at an object literal vs. normal code.
  • No var keyword, scoping is automatic.
  • No function keyword, functions look more like Python lambdas:
      // coffeescript
      square: x => x * x

      // resulting javascript
      var square = function square(x) {
          return x * x;
      };
  • Significant whitespace for scopes, a la Python.

Some of my favorite features:

Tail conditionals

    // coffeescript
    number = -42 if opposite_day
    
    // resulting javascript
    if (opposite_day) {
        number = -42;
    }

Comprehensions

    // coffeescript
    lunch: eat(food) for food in ['toast', 'cheese', 'wine']

    // resulting javascript
    var __a, __b, __c, __d, food, lunch;
    lunch = (function() {
        __a = ['toast', 'cheese', 'wine'];
        __c = [];
        for (__b in __a) {
            if (__a.hasOwnProperty(__b)) {
                food = __a[__b];
                __d = eat(food);
                __c.push(__d);
            }
        }
        return __c;
    })();

Inheritance and super

    // coffeescript
    Animal: =>
    Animal.prototype.move: meters =>
      alert(this.name + " moved " + meters + "m.")

    Snake: name => this.name: name
    Snake extends Animal
    Snake.prototype.move: =>
      alert("Slithering...")
      super(5)

    // resulting javascript
    var Animal, Snake;

    Animal = function Animal() {
    };
    Animal.prototype.move = function move(meters) {
        return alert(this.name + " moved " + meters + "m.");
    };

    Snake = function Snake(name) {
        return this.name = name;
    };
    Snake.__superClass__ = Animal.prototype;
    Snake.prototype = new Animal();
    Snake.prototype.constructor = Snake;
    Snake.prototype.move = function move() {
        alert("Slithering...");
        return Snake.__superClass__.move.call(this, 5);
    };

Multiline strings

    // coffeescript
    moby_dick = "Call me Ishmael. Some years ago --
    never mind how long precisely -- having little
    or no money in my purse, and nothing particular
    to interest me on shore, I thought I would sail
    about a little and see the watery part of the
    world..."

    // resulting javascript
    var moby_dick;
    moby_dick = "Call me Ishmael. Some years ago -- \
    never mind how long precisely -- having little \
    or no money in my purse, and nothing particular \
    to interest me on shore, I thought I would sail \
    about a little and see the watery part of the \
    world...";

There’s even an Underscore.coffee, a full port of Underscore.js to CoffeeScript! Awesome.