I’ve been using Coffeescript extensively over the last few weeks. Overall, I love it. The flexibility of the language and the clean, minimalist syntax occasionally causes problems, though. In this blog post, I’ve documented some of the pitfalls that have cost me hours of time. Each of these problems is the result of user error, but are also largely the result of language design choices. Hopefully reading this will save you from these pitfalls!

1. Optional Function Parenthesis and Spacing
The low down: a - 1 is math, a -1 is a function call.
Advice: Always place spaces on both sides of mathematical operators, and think about whether your code could be interpreted as an argument list.

Example Coffeescript:

1
2
3
4
5
6
7
a = 1
if (a - 1 == 0)
    b = 2
if (a-1 == 0)
    b = 2
if (a -1 == 0)
    b = 2

Resulting Javascript:

1
2
3
4
5
6
7
8
9
10
a = 1;
if (a - 1 === 0) {
    b = 2;
}
if (a - 1 === 0) {
    b = 2;
}
if (a(-1 === 0)) {
    b = 2;
}

2. Safely Iterating Backwards
The low down: Converting a C-style for loop to for i in [array.length - 1 .. 0] produces unexpected behavior when array.length = 0.
Advice:When you intend to iterate by -1, add by -1 to the end of your for statement to ensure that you never iterate from [-1..0]

Example Coffeescript:

1
2
3
4
5
6
7
# Bad - calls array[-1] if array.length == 0
for x in [array.length - 1..0]
    array.splice(x, 1) if array[x] == true
 
# Good - no iteration occurs if array.length == 0
for x in [array.length - 1..0] by -1
    array.splice(x, 1) if array[x] == true

Resulting Javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
var x, _i, _j, _ref, _ref1;
 
for (x = _i = _ref = array.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; x = _ref <= 0 ? ++_i : --_i) {
    if (array[x] === true) {
        array.splice(x, 1);
    }
}
 
for (x = _j = _ref1 = array.length - 1; _j >= 0; x = _j += -1) {
    if (array[x] === true) {
        array.splice(x, 1);
    }
}

Even with these pitfalls, Coffeescript is a great language. It’s incredibly readable and provides class structures that make it easy to write object-oriented javascript. Loose rules governing parenthesis and brackets mean that Coffeescript is sometimes ambiguous – “a -1″ could be a function call, or basic algebra. However, the ability to leave off parenthesis makes for beautiful function declarations.

Know of more Coffeescript syntax pitfalls? Help me make this blog post a great resource—let me know what you think in the comments and I’ll cite you!