BT

CoffeeScript - JavaScript the Good Parts

by Michael Hunger on Aug 05, 2010 |

At the recent Emerging Languages Conference (a part of OSCON), Jeremy Ashkenas the lead developer of DocumentCloud and creator of underscore.js, presented CoffeeScript, a language that is cross compiled to JavaScript.

Just today CoffeeScript version 0.9.0 was released. The main, compatibility breaking change was to change the assignment operator from colon : to the more JavaScript like equals sign =. This very much discussed step was mainly done to enable YAML style object literals and named parameters. Half assignments (a : or 'default') were also removed from the language. Some improvements have been introduced to the (optional) class inheritance system.

There are other such languages, but as we'd like to cover here, CoffeeScript differs in intent and features. Jeremy provided many insights in answering our questions. His answers are reflected in the article.

Jeremy worked extensively with JavaScript and experienced its shortcomings firsthand. He sums up the intent behind his language:

CoffeeScript is a simple thought experiment to imagine a language that exposes a minimal syntax for the beautiful object model that underlies JavaScript. There are three main aspects to doing that: Having a lighter syntax, cleaning up the semantics of broken JavaScript constructs, and providing bonus language features as shorthand for common JavaScript patterns. CoffeeScript's target audience is folks who want to write readable code that runs in the browser, and want to avoid the dark alleys of JavaScript while embracing the good parts.

 

With the recent introduction of powerful JS engines (such as V8 and Nitro) JavaScript became a very fast and powerful dynamic language. Its omnipresence in web applications and recently in event driven, non-blocking server runtimes (such as Node.js) makes it a critical language of the near future. Besides performance and familiarity with the language, a new factor is the reuse of JavaScript code and libraries on client and server. Especially the domain model, validations and application logic can be shared.

Jeremy is very clear on that: "The first person to create a pleasant end-to-end system for programming JavaScript web applications wins the next five years of web development, period."

These reasons made it obvious for Jeremy to focus on JavaScript as target platform. While based on JavaScript, CoffeeScript is heavily influenced by Python, functional languages like Haskell and of course EcmaScript 5 and many of the suggestions from the EcmaScript Harmony Wiki. The three main areas that CoffeeScript focuses on are:

Syntactic cleanup

  • Python style significant whitespace
  • implicit parentheses
  • no semicolons
  • String continuations
  • concise function literals
  • YAML style object literals

Semantic enhancements

  • everything is an expression (returns a value)
  • all variables in local lexical scope, no pollution of global scope
  • simple assignment and variable declarations, destructuring assignments
  • switch statements compiled to if-then-else chains
  • chain comparisons
  • named parameters

Goodies

  • variable arguments lists (splats)
  • literate programming (write the code within its documentation)
  • pythons range, array and object comprehensions
  • existential (elvis) operator
  • explicit strong binding of current self to function with => Hashrocket operator
  • fast and working class based inheritance support, based on the google.inherit approach
  • support for static inheritance and automatic delegation to superclass methods
  • heredocs, multiline strings, literal regexps, string interpolation/substitution
  • Cake a simple build system similar to Rake
  • <script type="text/coffeescript"> tags, minified coffescript compiler for inline use

Some examples taken from the documentation show the features.

# Assignment:
number   = 42
opposite = true

# Conditions:
number = -42 if opposite

# Functions:
square = (x) -> x * x

# Arrays:
list = [1, 2, 3, 4, 5]

# Objects:
math =
  root:   Math.sqrt
  square: square
  cube:   (x) -> x * square x

# Named (like) parameters
fun key : value 
(compiled to call({key: value}); )

# Splats:
race = (winner, runners...) ->
  print winner, runners

# Existence:
alert "I knew it!" if elvis?
# Accessor existence operator (null safe)
lottery.drawWinner()?.address?.zipcode

# Array comprehensions:
cubes = math.cube num for num in list

# Object comprehensions:
yearsOld = max: 10, ida: 9, tim: 11
ages = for child, age of yearsOld
  child + " is " + age

# Destructuring
[city, temp, forecast] = weatherReport "Berkeley, CA"
[open, contents..., close] = "".split("")
     
     # Functions and strong binding of this
     Account = (customer, cart) ->
       @customer = customer
       @cart = cart
     
       $('.shopping_cart').bind 'click', (event) =>
         @customer.purchase @cart
     
     # Regexp & String substitution
     sep =   "[.\\/\\- ]"
     dates = /\d+#sep\d+#sep\d+/g
     

Coffeescript can be installed by cloning the github repository and using the included build system Cake (similar to Rake) to build it (sudo bin/cake install). With npm, the Node Package Manager it is equally easy: sudo npm install coffee-script. Then the coffee compiler is available to compile CoffeeScript to JavaScript or execute it interactively.

coffee is a self hosted CoffeeScript compiler:

The trick with a self-hosted language is that you have to start with a place to stand. The original CoffeeScript compiler was written in Ruby. With 0.5.0, I did a fairly one-to-one port of the Ruby version to CoffeeScript, compiled that, ran the new compiler on it's own code, and then ran all of the tests with the self-compiled version. A heart-stopping moment, for sure. [...] Doing a self-hosting compiler keeps you honest. You stay sensitive to corner-case bugs, performance, and the cleanliness of the generated code.

 

As CoffeeScript is compiled source to source to JavaScript, some language features that have been requested (like negative array indexing) are not possible. At least not with access to the JS runtime.
Another aspect of cross compilation are runtime error traces and debugging the generated JavaScript. As line numbers won't match it is more difficult to relate the JavaScript code to the original CoffeeScript. That's why Jeremy took special care to create well readable JavaScript code and also suggests compiling beforehand and deploying/debugging the JS code directly. So CoffeeScript works as a code generator language.

Regarding the effort of creating CoffeeScript, Jeremy notes that it is no rocket science:

CoffeeScript is only 2,090 lines of code, all of it annotated, literate-programming-style. If you want to get your feet wet with a programming language that fits the way you want to code, I encourage you to borrow a runtime that you like, and to play with the source of some of the languages presented at the camp. Let a thousand little languages bloom.

A rich ecosystem has already evolved around CoffeeScript. Various commiters provided syntax highlighters for different editors and integration projects for node.js, Rhino, Rack, Python, Rails3 and Jammit.

You can listen to Jeremy talking about CoffeeScript at the TheChangeLog podcast episode 0.2.9 and the JSConf2010 presentation.

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Significant whitespace !?!? by jean-simon Larochelle

Interesting article on an interesting project however significant whitespace is a very bad idea.
Because of significant whitespace I will not use Python and therefore I would not use CoffeeByte either. I like to have a clear and unambiguous block delimiter in programming language and feel that significant whitespace is a "bug magnet".

Re: Significant whitespace !?!? by Luis Espinal

Interesting article on an interesting project however significant whitespace is a very bad idea.
Because of significant whitespace I will not use Python and therefore I would not use CoffeeByte either. I like to have a clear and unambiguous block delimiter in programming language and feel that significant whitespace is a "bug magnet".


Do you have any evidence that whitespace significance is a bad idea? I'm a Java developer (mostly), and from where I see it (and from the type of code entropy I've had to work and fix in the past), Python code looks extremely readable.

Whitespace significance is not about "ZOMG, I gotta get my space bar or tab counts right". It doesn't work that way. It is simply a manner to enforce nested blocks to have an indentation greater that their containing blocks.

Having work with a ton of Java, C, Basic (various flavours), and FoxPro code in the past, I can tell you that poor indentation is one of the top bug magnets. Some of the things we have made in the past has been to draw a line in the sand and force everyone to run their changes through a "standard" source code formatter (with manual deviations allowed mind you) before submitting them to version control.

Programmers, as unprofessional prima donnas many of them they are, kick and scream at the idea of having to run a formatter with "project standard" settings. After a while, and when they see their massive code bases having a uniform block indentation (specially if their code was originally a mess), they end up loving it.

Python simply does that at the syntactical level. And the rules whitespace significance are very simple. If a programmer has problems working with that to produce good code, that person should re-consider working in this profession, no offense.

There are more insidious bugs that are unavoidable - threading bugs, integration bugs, timing bugs. But bugs caused by whitespace significance???? What exactly are we talking about here?

Any concrete evidence of this?

Re: Re: Significant whitespace !?!? by jean-simon Larochelle

Well...I have been programming computers since around 1979 and I'm still doing it professionally so I guess that was not a bad career choice ;)

I admit that I am not totally rational about this issue and my irrational fear of significant whitespace goes back to programming on punch cards (IBM mainframe). In one program I wrote I accidentally started typing (punching) one column early and the assignment turned into a comment :(. I spent a good amount of time chasing that bug (this program was written in COBOL or FORTRAN). Now I will also admit that position on a punch card and significant whitespace is not exactly the same so what exactly is my problem with whitespace. The answer is probably that after so many years of Pascal, C/C++ and Java I am now so use to nice delimiters that I find code that don't use them difficult to understand.

So I guess the answer to your question is: no I don't have concrete (rigourous) evidence that significant whitespace is a source of bugs.

I guess that the kind of thing that make me nervous is people accidentally deleting blanks but from what your saying it sounds like this should not be a problem. I'm glad to hear that because I certainly agree with you that there is enough source of bugs as it is without accidental removal of blanks introducing more bugs.

I might just take another look at Python and CoffeeScript. Since I have written programs in language like x86 Assembly, APL, COBOL, C++, Java and others I should be able to learn those languages even with the significant whitespace.

Re: Re: Significant whitespace !?!? by Luis Espinal

In that case you more than double my software experience, and I should be careful who I write my e-jabs, don't I? :) Do I did study COBOL, I've never worked with it (and certainly not with punch cards - that got to be a nightmare. I can see in that case how it can be a bug magnet - here I can see your valid point.)

I do appreciate your candor in replying back, and don't get me wrong, I like nice delimiters, but I've had to deals with thousands of lines of code (the majority of it FoxPro and Java), that although have nice delimiters, they were poorly formatted to the point that it was impossible to get through them without some monumental effort.

And that the thing, delimiters do state unambiguously what they do... to the compiler. But there is nothing that forces the code around them to be readable enough. Barring some edge cases (code optimized for performance or space), it should speak its intention (a required attribute for maintainability.)

Significant space (or it should be called "syntactically enforced indentation") is an attempt to the later. For a good developer, it doesn't make a difference (since he already goes to lengths in enforcing indentation). I does forces the not-so-good developer to indent appropriately (and hopefully teaches him how to write readable, maintainable code.)

Don't get me wrong, I had the same worries about the concept, but once I delved into it, I'm hooked. I'm trying to get out of Java and into Python, Ruby or DSL-writing, preferably the first. It is really pure joy to do actual work in an environment that puts barriers to poorly indented software (the bane of my existence;)

Re: Re: Significant whitespace !?!? by Bharat Ruparel

Actually I have been programming almost as long as you have been and can share your negative experience with punched card Fortran (in my case) programming :) I have used HAML with Ruby on Rails which is addressing the same issue (ERBs) that CoffeeScript is trying to address with Javascript. I had hesitated to use HAML initially, but spending some time doing it got me over the in-built biases us old timers tend to have and soon I actually started liking it a lot as against ERBs (embedded ruby to produce dynamic web views). The white space "issue" turned out to be a non-issue, since with a nice HAML plugin by Tim Pope, my VIM editor takes the pain out of writing the code which actually reads a lot better than the ERBs. So I urge you to keep an open mind. I am certainly going to invest some time looking at CoffeeScript. JQuery has made Javascript approachable for me. A better syntax hopefully will move me further along.

Re: Re: Significant whitespace !?!? by jean-simon Larochelle

My original comment "I will never use Python and therefore I would not use CoffeScript either" was a extreme version of my real position that is probably more like: "I will think long and hard before using a language like Python or CoffeScript".
A project like CoffeScript is interesting and I might actually have a better look at it eventually. From the discussion here I get the feeling that significant whitespace might actually not be so bad.

Re: Re: Significant whitespace !?!? by Jim Cakalic

IMO, if a developer can't even indent their code reasonably then I don't trust their implementation, language choice is irrelevant. That having been said, and having used Python for commercial work, I detest the significant whitespace. My favorite quote to date:

Flamewars over whitespace styles (2/3/4/8 spaces per tabs, tabs vs physical spaces, even whining about the annoyance of the issue vs the sared beauty that is python - or so I've been told) are as annoying as flamewars over brace positioning - but the fact is that no matter how ugly your braces are, the meaning is never hidden by an editor setting that you forgot to check.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

7 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT