The worst thing about CoffeeScript

16 Dec 2013

I think CoffeeScript is mostly pretty great, but it has one feature related to variable scope that bit me more than once when writing shimmre. Here's some Python:

a = 1

def contrived():
  a = 2
  return a

contrived() # 2
a           # 1

And some CoffeeScript:

a = 1

contrived = -> a = 2; a

contrived() # 2
a           # 2

Clobbering assignments in an enclosing scope is useful in some cases, but if it has to be the default behavior, it would at least be nice to have some way to override it - in JavaScript that's what var is for. Alas:

This behavior is effectively identical to Ruby's scope for local variables. Because you don't have direct access to the var keyword, it's impossible to shadow an outer variable on purpose, you may only refer to it. So be careful that you're not reusing the name of an external variable accidentally, if you're writing a deeply nested function.

In other words, be sure to remember every variable name you've ever used in any scope where you define a function, or else risk creating some really frustrating bugs. This behavior isn't usually a problem in Ruby, since the bodies of classes and methods defined using the class and def keywords aren't evaluated in the enclosing lexical scope. But in CoffeeScript it's terrible!