As part of my day job at Shopify I’ve been implementing a new front end using the language CoffeeScript. Originally, the front-end was regular JavaScript, but since Rails 3.1 will be supporting CS we might as well start using it.
As a whole, the language isn’t that bad. I do appreciate many of the helpers it provides for enumerating hashes and arrays, and bindings (aka fat arrow) are awesome. It’s made writing some complex client code that relys on context far easier, especially since the new features like .bind aren’t available on most (if any) mobile devices (although this is easily fixed with something like 5 lines of code).
My main complaints about CS are with some of the edge cases it has. For example, I needed to have a bound anonymous function within a setTimeout. In JS I would typically perform something similar to:
setTimeout(
// May be a little bit off here, but I think that's how to do ECMA5 binds
function(){ this.doSomething(); }.bind(this),
150);
The above is fairly straight forward, and the language doing anything I’d consider unexpected. Though if we were to do the same thing in CS, I’d expect it to be something like this:
setTimeout( => @doSomething(), 150)
This actually doesn’t work, the coffee compiler will complain. It’s somewhat understandable, there some weird stuff going on here and it’s difficult to parse. A solution I often used was this:
setTimeout( (=> @doSomething()), 150)
Now I have all these extra brackets that I shouldn’t need, and it’s frustrating because I’m trying to use th language the way it seems to have been designed. Now this had been bothering me for some time now, and decided to twitter rage/complain about it. This did get some attention from someone who runs the CS twitter account who gave me some suggestions. Those of which I found to be somewhat hacks, or wouldn’t work in my case.
One solution was to have (in my case) the fetch method bound to the products instead of having a fat arrow function declaration. Now, since the actual model that products Points to is a Spine model, I really don’t feel like going in and hacking something (that already works the way I want/expect) for such a minor (but annoying) problem with CS. Another solution was to essentially create a function that is in essence setTimeout but reversed, so it’s something like:
delay = (delay, function) ->
setTimeout(function, delay)
Which I’m also not super keen on, once again it’s going through a bunch of extra steps to fix an inherent problem with the language itself. Now I often do mix up the arguments used in setTimeout, and I would love to see that get fixed/added in the future.
I mentioned the problem I was having to one of our awesome (and way smarter than me) interns about it and he actually came up with an almost perfect solution.
setTimeout( =>
@doSomething()
,150)
Aside from that preceding comma and needing to remember to un-indent, it’s not a big deal and I like that I’m not having to go in and hack apart Javascript to fix minor issues.
Although I do seem to be a bit bitter about my experience with CoffeeScript, I do have to say that I like what the language is bringing to the table, I just hope it gets some improvements for CS 2.0 or something. Perhaps having some kind of explicit scope declaration (like begin end or curly brackets), would help out a fair amount. Though, I think I can keep dreaming for having curly brackets, there seems to be some kind of aversion towards them.