A few weeks ago, it was announced that Ruby on Rails 3.1 will include jQuery, Sass (using SCSS) and CoffeeScript as default dependencies. Among these, CoffeeScript seems to be the controversial dependency, at least if you read the comments on the actual commit (check out the funny meme pictures).
Whitespace vs. semi-colons and curlies
The first thing you notice about CoffeeScript is that it lacks curly braces and semi-colons. Instead, CoffeeScript uses significant whitespace to delimit blocks of code, just like Python, Haskell and some other languages. If you’re not used to this, this feature of the language is going to bite you first.
Please notice how slick it is to define functions in CoffeeScript:
add = (x, y) -> x + y square = (x) -> x * x
If you know C#, this syntax is very similar to C#’s lambda syntax:
var add = (x, y) => x + y var square = x => x * x
(Note that writing parenthesis around the argument(s) is mandatory in CoffeeScript, which is not the case for single argument lambdas in C#.)
When calling a function, parentheses are optional and arguments are separated with commas (like Ruby):
two = add 1, 1 four = square 2
A Y combinator example
# Y combinator in CoffeeScript Y = (le) -> ((f) -> f(f))((f) -> le (x) -> f(f) x)
If needed, could be inserted to make the code a little bit more readable.
Y = (le) -> ((f) -> f(f)) ((f) -> le((x) -> f(f)(x)))
(If we would have omitted the , then we would have gotten an compiler error, since Y would have been defined as only the first line of code and then CoffeeScript would have found the second line as mis-indented. You could also play around with placing the parenthesis differently, if you don’t like to use .)
Another CoffeeScript feature worth mentioning is array comprehensions. An array comprehension that prints the square of all the even numbers looks like this:
numbers = (num * num for num in [1..100] when num % 2 == 0)
As I see it, array comprehensions could be useful if you have very long lists and don’t want to take the penalty of calling a function on each item, as you would do in for example jQuery, underscore.js or the native Array.forEach (implemented in some browsers).
Other features that I like are the do keyword and the fat arrow (=>). Briefly, do helps you create closures in a loop, avoiding this problem. The fat arrow (=>) binds the value of this to the context that defines the function and not the context that calls the function (see why this is needed here).
And, of course, if you choose to use CoffeeScript in a project, you have yet another language for a new member of the team to learn. For experienced web developers this may not be an issue, but for developers that don’t have that much experience in web development I guess that it could be frightening at first sight.
I really like my first impressions of CoffeeScript and I’m eager to learn more about it. Please do as I did and try the embedded CoffeeScript interpreter (under the “Try CoffeeScript” link) after reading the first examples.
And remember to have fun! :)