Coffeescript Static Analysis / Static Typechecking - Roadblocks

coffeescript, javascript, programming-languages, static-analysis

Solution

This answer is a bit of a brain dump since I'm interested in this also. Hope it helps.

I use the Google Closure Compiler to statically analyze the code that CoffeeScript generates. It has a really good static analyzer, and I'm not sure if there's a good reason to reinvent the wheel here. The easy way is to just write the annotations by hand:

###*
   * @param {number} x
   * @param {number} y
   * @return {number}
###
adder = (x, y) -> x + y

It's a bit verbose, but on the other hand you're borrowing the static analysis abilities of the closure compiler which is really powerful and is able to check a lot. I actually write type annotations in a slightly more concise way, then have a script to rewrite the coffee file. My code ends up looking like this:

#! {number} x {number} y @return {number}
adder = (x, y) -> x + y

I'm sure you can see that the rewriter is pretty straightforward.

A quick note before I move on. Be sure to compile your code with `-b` (bare) if you're running it through the closure compiler. The closure compiler is pretty good, but it's not smart enough to do data flow analysis. CoffeeScript wraps your code in an anonymous function by default, which will trip up the compiler.

Another option along the same path (this would break compatibility with CoffeeScript, but would be a lot cooler) would be to have the Coffee compiler compile something like this:

adder = (number x, number y): number -> x + y

into JS like this:

/***
  * @param {number} x
  * @param {number} y
  * @return {number
  */
var adder = function(x, y) {
  return x + y;
};

which could then be fed into the closure compiler on a compile - if there were no errors the compiler could then strip all the comments out.

Indeed, this guy appeared to be doing exactly this. Sadly, his work seems to be in an incomplete state.

In all of these cases, we defer the hard work - static typechecking - to the closure compiler. If you don't want to do this, I'd understand, but it'd be tough to convince me that it's worthwhile to build a whole new static analysis tool from scratch. :)

EDIT a year later: I just use typescript these days. :)

Problem

I think Coffeescript is an awesome language! I was looking for some projects / issues / features that add Static Analysis to Coffeescript. However after some searching I found that the Coffeescript faq and this page suggest that static analysis might not be viable. I was wondering that if there is a fundamental issue in implementing static analysis / static type checking in Coffeescript, because of which something of this sort does not already exist in the compiler? Also, is it something that is not possible to do for non trivial checks but might work only for straightforward analysis? When I say straightforward I mean checking for trivial stuff like, whether the user has defined a function twice by the same name (in a class) or on the top level (or perhaps on the top level in a collection of related .coffee files). I would appreciate if anyone could please point out some examples that show why implementing static analysis / type checking is not straightforward / possible / worth spending time on? Thank you very much!

Original source