CoffeeScript Oddities

I really want to use CoffeeScript, a cleaner syntax for JavaScript. Unfortunately, there are too many inconsistencies and oddities that I find frustrating. The main problem is that CoffeeScript considers whitespace to be significant, but the implementation doesn’t handle it well. I guess the CoffeeScript community sees these as features instead. Here are some examples:

Coffeescript is easily confused by whitespace. Of the following expressions, all work as expected except the last one. It thinks the last one is a function call, where “a” is the function and “+b” is a parameter. I don’t know what “+b” means. Most parsers would look for a left-hand side for that expression.

Coffeescript does not allow you to define variables with “var” as in JavaScript. It generates the “var” declarations in the correct lexical scope. But it can get confused with names and doesn’t (AFAIK) have a convenient way to tell the compiler what to do. Since JavaScript’s namespace is a wild mess, defining variables correctly is quite important.

There are other little issues which are a matter of taste, not functionality. For example, if-then-else statements are weird. It reserves the “then” keyword for one-liners, but doesn’t use it for normal if/else statements. Or with

x = if cond then val1 else val2
x = if cond
val1
else
val2

If JavaScript continues to annoy me I may fork CoffeeScript and patch up these problems for my own use. On the other hand, scheme2js might be a winner.

Share this:

Like this:

Related

2 comments

The `a +b` thing has been discussed a lot. Unfortunately, `+b` is a handy way of converting `b` to a number in JavaScript, so treating `a +b` as `a(+b)` is really the only sensible thing for CoffeeScript to do (given that parentheses are optional).

I was taken aback by `r1 = e for e in l` vs. `r2 = (e for e in l)` at first, too, but I’ve come to terms with it. The rules are consistent: Everything left of `for` is a single expression, and `for` loops return a list of their results. That’s it.

The approach to scope should be familiar to folks coming from Ruby or Python. The idea is to avoid confusion by preventing the existence of an `a` with global scope and an `a` with local scope (shadowing the global). Maybe shadowing from function arguments shouldn’t be allowed, either.

I hope you’ll continue to use CoffeeScript in the future. There are compromises, to be sure, but it’s a very powerful language that stays close to JavaScript’s semantics.

Like you, I do not like indentation being used to define blocks (which is probably what you meant by ‘whitespace is significant’).

The second thing I do not like is that, if a person starts coding in CoffeeScript and uses it in preference to Javascript, what happens when they venture into the wild world and encounter Javascript? The last thing I want to do is train a developer in CoffeeScript, then they encounter some Javascript somewhere that they have to read and debug, and they end up making elementary errors like defining global variables without ‘var’ because they were never taught to do this from the beginning (never taught = “never had it hammered into them so it actually stuck in their minds”). Not everyone is a grade A developer, and thus can’t be trusted to ‘do the right thing’ without lots of training and practice.