On CoffeeScript

July 15th, 2013

I had a project that was almost entirely JavaScript come up with a decent timeline on it. Not to be one to have a completely uninformed opinion I decided that this would be an appropriate time to actually use CoffeScript and find out whether it was worth it.

By way of background I have been a Ruby and JavaScript developer for several years. I'm openly biased against indentation delimited languages, simply because I find them annoying to work in and this has so far caused me to avoid using CoffeeScript for much of anything beyond hello world.

The following are the highlights of just over two weeks of intense development, all of the JavaScript was written in CoffeeScript.

The Good

CS adds a lot of syntactic sugar and some of it is on top of JS's prototypes where it creates a clean and effective way of inheriting prototypes. If there is one feature in CS I would emphasize as being awesome, it is the addition of a properly functioning super keyword.

CS adds language level syntax for binding a function to a context => eliminating the need for library level shims such as underscore's _.bind and the line. It's an effective way to eliminate an extra method call or manual variable assignment.

It adds simplifying syntax helpers such as ||= and unless. These help smooth out the language, make it more usable, less verbose and easier to read. It has a bunch of syntax sugar which JS desperately needed and as a Ruby dev I always found I wanted.

The Neutral

CS subtly (and not so subtly) changes the meaning of several core pieces of JS. The most notable examples during my weeks using it were the assumption of local scope, and the global substitution of == for ===.

The assumption of local scope is a fantastic idea for JS. If you define a variable, 99% of the time you want it only in the method or script where you define it, but bare JS assumes that if you didn't put var in front of it, you wanted it globally. CS makes the more rational assumption that you wanted it locally. This can be slightly annoying in the case of defining classes, where it still makes this assumption. I can easily see an argument for consistency over shortening the syntax by a few window. lines, so I'm not up in arms over it.

I had one major concern of the debuggability going in to using CS. In the end, this concern was moot. CS's generated code closely resembles your original and telling where each line came from is quite easy. For those more concerned there is the option of turning on source maps, which allow your debugging environment to link the js source with cs source. I think this was also mitigated by the fact that I already code in small, maintainable modules which are well-namespaced (as well as you can in JS).

The substitution of all == for === is similar. 90% its what you want, but the rest of the time when you were expecting a coercive check it can bite you. Being aware of it solves most of the cases, but it also causes corner cases.

The Bad

With CS's assumption of non-coercive checks for all your equality checks. If you want a coercive check, for instance you have a select drop down that has the id in the value field, but the id is stored as an integer in your models, you have to escape the check and it will be injected as pure JS. This is fairly easy utilizing backticks. No problem, right?

No problem. Until you use the aforementioned =>. CoffeeScript achieves the binding effect by setting a variable of _this and replacing your calls to this with _this. Unfortunately, if you use backtick escaping, it doesn't replace your this and you have to manually change your reference to _this inside the backticks. Annoying.

Another point of frustration was with CoffeeScript's optional parenthesis syntax. On the surface, this is a great idea as examples by the bare words approach to Ruby methods. The problem comes from JavaScript's nature of first-order functions. In JavaScript you are constantly passing around method references. The problem is that calling a method with no arguments requires the parenthesis. I frankly can't see a way they could have done it better and its a minor concern in the first place.

Conclusion

CoffeScript adds tons of refinements, cleanups and outright improvements to JavaScript. In general its a worthwhile endeavor. Through working with it for a few weeks I am definitely not where I expected to be. I expected to greatly and severely dislike it. Instead I find it helpful but the fact that I have to repeatedly tell the editor where to indent things for syntax reasons is at best annoying and at worst infuriating. I'm not pleased repeatedly receiving "Unexpected Outdent" syntax errors and breaking out the snacks while I count goddamned spaces and look for where I accidentally hit tab.

What do you tell CoffeeScript when you have a bloody finger? Nothing you didn't already tap tab a thousand times to tell it.

CoffeeScript is worth using. But the first person to fork it and give me Ruby style block syntax gets a parade and a holiday named after them.

0 replies

New comments are disabled.