Tuesday, August 2, 2011

An Examination of goog.base()

A few weeks ago, I started working on adding an option to CoffeeScript to spit out Closure-Compiler-friendly JavaScript. In the process, I discovered that calls to a superclass constructor in CoffeeScript look slightly different than they do in the Closure Library. For example, if you have a class Foo and a subclass Bar, then in CoffeeScript, the call [in the generated JavaScript] to invoke Foo's constructor from Bar's looks like:
Bar.__super__.constructor.call(this, a, b);
whereas in the Closure Library, the canonical thing is to do the following, identifying the superclass function directly:
Foo.call(this, a, b);
The two are functionally equivalent, though CoffeeScript's turns out to be slightly simpler to use as a developer because it does not require the author to know the name of the superclass when writing the line of code. In the case of CoffeeScript, where JavaScript code generation is being done, this localization of information makes the translation of CoffeeScript to JavaScript easier to implement.

The only minor drawback to using the CoffeeScript form when using Closure (though note that you would have to use superClass_ instead of __super__) is that the CoffeeScript call is more bytes of code. Unfortunately, the Closure Compiler does not know that Bar.superClass_.constructor is equivalent to Foo, so it does not rewrite it as such, though such logic could be added to the Compiler.

This piqued my curiosity about how goog.base() is handled by the Compiler, so I ended up taking a much deeper look at goog.base() than I ever had before. I got so caught up in it that I ended up composing a new essay on what I learned: "An Examination of goog.base()."

The upshot of all this is that in my CoffeeScript-to-Closure translation code, I am not going to translate any of CoffeeScript's super() calls into goog.base() calls because avoiding goog.base() eliminates a couple of issues. I will still use goog.base() when writing Closure code by hand, but if Closure code is being autogenerated anyway, then using goog.base() is not as compelling.

Finally, if you're wondering why I started this project a few weeks ago and have not made any progress on the code since then, it is because I got married and went on a honeymoon, so at least my wife and I would consider that a pretty good excuse!

Want to learn more about Closure? Pick up a copy of my new book, Closure: The Definitive Guide (O'Reilly), and learn how to build sophisticated web applications like Gmail and Google Maps!