Thursday, April 12, 2012

Step minus 1 - Re-Writing Everything

I don't know if this step is forwards or backwards... A colleague at work had been posting about CoffeeScript . It's a scripting language that compiles into JavaScript. Although skeptical, I tried it and absolutely fell in love with it! So I rewrote everything.

If you know Python or Ruby, CoffeeScript is a more natural way to program than JavaScript. And the code it generates is way better than (my crappy) JavaScript code. Even with the relatively small codebase I was trying convert, I still found 4 major JS coding errors in the conversion process. Any one of those would have caused a long, painful debugging session. And CoffeeScript fixes a lot of JS problems like that auto-magically!

So I decided to re-write everything. In my limited experience there are three ways to rewrite code:
  1. Don't. If everything is already working, just use the code you have as modules and don't worry about what's inside those black boxes.
  2. Make small changes, test them, make some more changes, test them, etc. Otherwise known as the 'smart approach'.
  3. Make a huge amount of changes in a language you've never used before and then spend the next few weeks tracking down the bugs while simultaneously trying to learn the new language. A.K.A. the fun approach :-)
Obviously, I chose #3.

My experience with CoffeeScript was pretty straight-forward:

Install
The install with node.js's npm was super-easy, and well-documented:

npm install -g coffee-script

Set up

There are a lot of ways to run CoffeeScript. The method I chose was to have it monitor all of the JavaScript that I was writing and whenever it detected a difference it would automatically compile that script. The terminal window showed any compile-time errors after each save.

Another option I liked was the -join option. It takes all of the CoffeeScripts you specify and outputs them into a single file. So in order to start using CoffeeScript I would just cd to the correct directory and issue the following command:


coffee --watch --compile --join uno.js *.coffee


I had an individual coffeescript file for each object and it all compiled into a single JS file 'uno.js'.

Found Errors

Some of the biggest errors CoffeeScript found and fixed automatically for me were in the board module where I was accidentally declaring some variables as global. ( Note to the JavaScript language designers: global variables by default? Seriously? )

My Toughest CoffeeScript Error to Debug

The actual re-writing didn't take much time... except for one bug. I was calling the _drawStone method for one class. The method didn't take any parameters so I wrote the call as:

@_drawStone

( The @ symbol is like the 'this' keyword. So that would be equivalent to this._drawStone )

This might initially seem like an odd decision, however, it kind of makes sense because the parentheses are optional for function calls with parameters, so I left them off of the parameter-less call as well. However, it should have been:

@_drawStone( )

The main problem was that the CoffeeScript compiler didn't raise this as an issue. No warning, no runtime, error, nothing... I checked the line and it compiles into:

this._drawStone;

What does that even mean? It creates a property but it has no value assigned to it. Why would anybody do that? I lost 20 hours of my life tracking this down :-(

The only thing that made me feel any better was that I wasn't the only person who ran into this:

https://github.com/jashkenas/coffee-script/issues/514

https://github.com/jashkenas/coffee-script/issues/1412

I may enter this as a request to raise a warning during the compile phase and see what they say...

Edit: Before opening the request I did my due diligence and found out this had been opened before ( https://github.com/jashkenas/coffee-script/issues/988 ) The comments mentioned why this would be such a tricky problem to fix... I may just change my coding style and always use parentheses, even when they're not required.

A Great Resource

If you want to learn CoffeeScript one of the best resources is Alex MacCaw's great book The Little Book of CoffeeScript .