Dropbox dives into CoffeeScript

Posted by Dan Wheeler, Ziga Mahkovec, Chris Varenhorst on September 13, 2012

During July’s Hackweek, the three of us rewrote Dropbox’s full browser-side codebase to use CoffeeScript instead of JavaScript, and we’ve been really happy with how it’s been going so far. This is a controversial subject, so we thought we’d start by explaining why.

CoffeeScript:

JavaScript:

By the way, the JavaScript has a scoping bug, did you catch it??

We’ve heard many arguments against CoffeeScript. Before diving in, we were most concerned about these two:

  1. That it adds extra bloat to iterative development, because each tweak requires recompilation. In our case, we avoided this problem entirely by instrumenting our server code: whenever someone reloads a Dropbox page running on their development server, it compare mtimes between .coffee files and compiled .js equivalents. Anything needing an update gets compiled. Compilation is imperceptibly fast thanks to jashkenas and team. This means we didn’t need to change our workflow whatsoever, didn’t need to learn a new tool, or run any new background process (no coffee --watch). We just write CoffeeScript, reload the page, loop.
  2. That debugging compiled js is annoying. It’s not, and the main reason is CoffeeScript is just JavaScript: it’s designed to be easy to debug, in part by leaving JavaScript semantics alone. We’ve heard many arguments for and against debuggability, and in the end, we convinced ourselves that it’s easy only after jumping in and trying it. We converted and debugged about 23,000 lines of JavaScript into CoffeeScript in one week without many issues. We took time to test the change carefully, then slowly rolled it out to users. One week after Hackweek had ended, it was fully launched.

Probably the most misleading argument we hear against CoffeeScript goes something like this: If you like Python or Ruby, go for CoffeeScript — it’s really just a matter of syntactic preference. This argument frustrates us, because it doesn’t consider history. Stick with us for a minute:

  • April 1995: Brendan Eich, a SICP enthusiast, joins Netscape with the promise of bringing Scheme to the browser.
  • He’s assigned to other projects in the first few months that he joins. Java launches in the meantime and explodes in popularity.
  • Later in ’95: Scheme is off the table. Upper management tasks Eich with creating a language that is to Java as VBScript is to C++, meant for amateurs doing simple tasks, the idea being that self-respecting pros would be busy cranking out Java applets. In Eich’s words:

    JS had to “look like Java” only less so, be Java’s dumb kid brother or boy-hostage sidekick. Plus, I had to be done in ten days or something worse than JS would have happened.

    Imagine Bruce Campbell Brendan Eich as he battled sleep deprivation to get a prototype out in 10 days, all the while baking his favorite concepts from Scheme and Self into a language that, on the surface, looked completely unrelated. LiveScript is born. It launches with Netscape Navigator 2.0 in September ’95.

  • December ’95: For reasons that are probably marketing-related and definitely ill-conceived, Netscape changes the name from LiveScript to JavaScript in version 2.0B3.
  • August ’96: Microsoft launches IE 3.0, the first version to include JavaScript support. Microsoft calls their version “JScript” (presumably for legal reasons).
  • November ’96: ECMA (Now Ecma) begins standardization. Netscape and Microsoft argue over the name. The result is an even worse name. Quoting Eich, ECMAScript “was always an unwanted trade name that sounds like a skin disease.”

Especially considering the strange, difficult and rushed circumstances of its origin, JavaScript did many things well: first class functions and objects, prototypes, dynamic typing, object literal syntax, closures, and more. But is it any surprise that it got a bunch of things wrong too? Just considering syntax, things like: obscuring prototypical OOP through confusingly classical syntax, the var keyword (forgot var? congrats, you’ve got a global!), automatic type coercion and == vs ===, automatic semicolon insertion woes, the arguments object (which acts like an array except when it doesn’t), and so on. Before any of these problems could be changed, JavaScript was already built into competing browsers and solidified by an international standards committee. The really bad news is, because browsers evolve slowly, browser-interpreted languages evolve slowly. Introducing new iteration constructs, adding default arguments, slices, splats, multiline strings, and so on is really difficult. Such efforts take years, and require cooperation among large corporations and standards bodies.

Our point is to forget CoffeeScript’s influences for a minute, because it fixes so many of these syntactic problems and at least partially breaks free of JavaScript’s slow evolution; even if you don’t care for significant whitespace, we recommend CoffeeScript for so many other reasons. Disclaimer: we love Python, and it’s Dropbox’s primary language, so we’re probably biased.

An interesting argument against CoffeeScript from Ryan Florence, that seemed plausible to us on first impression but didn’t hold up after we thought more about it, is the idea that (a) human beings process images and symbols faster than words, so (b) verbally readable code isn’t necessarily quicker to comprehend. Florence uses this to argue that (c) while CoffeeScript may be faster to read, JavaScript is probably faster to comprehend. We’d expect cognitive science provides plenty of evidence in support of (a), including the excellent circle example cited by Florence. (b) is easily proven by counterexample. Making the leap to (c) is where we ended up disagreeing:

  • For the most part CoffeeScript isn’t trading symbols for words — it’s dropping symbols. Highly repetitive symbols like , ; {} (). We believe such symbols mostly add syntactic noise that makes code harder to read.
  • CoffeeScript introduces new symbols! For example, (a,b,c) -> ... instead of function (a,b,c) {...}. Along with being shorter to type, we think this extra notation makes code easier to comprehend, similar to how math is often better explained through notation instead of words.
  • Consider one example where CoffeeScript does in fact swap a symbol for a word: || vs or. Is || really analogous to the circle in Florence’s example, with or being the verbal description of that circle? This needs the attention of a cognitive scientist, but our hunch is || functions more linguistically than it does symbolically to most readers, acting as a stand-in for the word or. So in this case we expect something more like the reverse of the circle example: we think || and or are about equally readable, but would give slight benefit to CoffeeScript’s or, as it replaces a stand-in for or with or itself. Humans are good at mapping meanings to symbols, but there’s nothing particularly or-esque about ||, so we suspect it adds a small amount of extra work to comprehend.

On to some code samples.

Before and after shots

JavaScript CoffeeScript

if (files) {
  BrowseDrag._update_status_position(e, files);
} else if (e.dataTransfer &&
           e.dataTransfer.types &&
           e.dataTransfer.types.contains('Files')) {
  CrossDomainUploader.show_drop_indicators(e);
}

if files
  @_update_status_position e, files
else if e.dataTransfer?.types?.contains 'Files'
  CrossDomainUploader.show_drop_indicators e

this.originalStyle = {};
['top', 'left', 'width', 'height'].each(function (k) {
  this.originalStyle[k] = this.element.style[k];
}.bind(this));

@originalStyle = {}
for k in ['top', 'left', 'width', 'height']
  @originalStyle[k] = @element.style[k]

Sharing = {
  init: function (sf_info) {
    [sf_info.current, sf_info.past].each(function (list) {
      list.each(function (info) {
        Sharing._decode_sort_key(info);
      });
    });
  }
}

Sharing =
  init: (sf_info) ->
    for list in [sf_info.current, sf_info.past]
      for info in list
        @_decode_sort_key info

 

We’ll let this comparison speak for itself. We consider it our strongest argument in favor of CoffeeScript.

Statistics

JavaScript CoffeeScript
Lines of code 23437 18417
Tokens 75334 66058
Characters 865613 659930

 

In the process of converting, we shaved off more than 5000 lines of code, a 21% reduction. Granted, many of those lines looked like this:

      });
    });
  }
}

Regardless, fewer lines is beneficial for simple reasons — being able to fit more code into a single editor screen, for example.

Measuring reduction in code complexity is of course much harder, but we think the stats above, especially token count, are a good first-order approximation. Much more to say on that subject.

In production, we compile and concatenate all of our CoffeeScript source into a single JavaScript file, minify it, and serve it to browsers with gzip compression. The size of the compressed bundle didn’t change significantly pre- and post-coffee transformation, so our users shouldn’t notice anything different. The site performs and behaves as before.

Methodology

Rewriting over 23,000 lines of code in one (hack)week was a big undertaking. To significantly hasten the process and avoid bugs, we used js2coffee, a JavaScript to CoffeeScript compiler, to do all of the repetitive conversion tasks for us (things like converting JS blocks to CS blocks, or JS functions to CS functions). We’d start converting a new JS file by first compiling it individually to CS, then manually editing each line as we saw fit, improving style along the way, and making it more idiomatic. One example: the compiler isn’t smart enough to convert a JS three-clause for into a CS for/in. Instead it outputs a CS while with i++ at the end. We switched each of those to simpler loops. Another example: using string interpolation instead of concatenation in places where it made sense.

To make sure we didn’t break the site, we used a few different approaches to test:

  1. Jasmine for unit testing.
  2. We built a fuzz tester with Selenium. It takes a random walk across the website looking for exceptions. Give it enough time, and it theoretically should catch ‘em all ;)
  3. Tons of manual testing.

Going Forward

Dropbox now writes all new browser-side code in CoffeeScript, and we’ve been loving it. We’ve already written several thousand new lines of coffee since launching in July. Some of the things we’re looking to improve in the future:

  • Browser support for CoffeeScript source maps, so we can link JavaScript exceptions directly to the source code, and debug CoffeeScript live.
  • Native CoffeeScript support in browsers, so that during development, we can avoid the compilation to JavaScript altogether.

Thanks

To Brendan Eich and Jeremy Ashkenas for creating two fantastic languages.

  • http://ryanflorence.com Ryan Florence

    For the record, I actually really really love CoffeeScript now.

    http://ryanflorence.com/2012/javascript-coffeescript-rewrite/

    • Dan Wheeler

      Nice! We included your earlier argument because we thought it was interesting and enjoyed thinking about it. Glad to see we agree :)

      • http://ryanflorence.com Ryan Florence

        Also, you’re spot on with the symbols thing.

        Side note: We’ve left our JS alone, didn’t want to kill git blame history to see why some pieces of code were there. We simply pull out pieces as we work on them to CoffeeScript, one day it’ll all be converted.

        • Dan Wheeler

          makes sense, losing blame history is a big downside to our approach. we converted mostly because we tweak and extend existing code so frequently, and it would have been hard to separate new coffee from old js. (having a codebase in one consistent language and style is helpful too, but wasn’t really our starting point; our 3rd party libs are all still in js for example.)

  • Justin Thomas

    Scoping bug:  for(var i…  :)

    • Dan Wheeler

      heh, nope, the bug is inside the loop ;) 

    • threedot

      This is not bug, only language feature. JavaScript isn’t a block-scope language. JavaScript is a function-scope language. This approach extending with JavaScript 1.7 let keyword.

      To create local scope variable in function, you may use var keyword.
      To create local scope variable in statement group use let keyword.

      You may use following line with JavaScript 1.7.

      for (let i = 0; i < 100; i++) ;

  • Hawiohou

    Did you find any bugs in the Javascript on the way through?

  • http://twitter.com/josephzhou Joe Zhou

    Coffee is def easier to maintain and read, syntax wise, eh everyone has his/her own opinion. 

  • Matthew

    How much did CoffeeScript increase the size of gzip’d JavaScript? CoffeeScript loops and comprehensions can be very verbose (if faster at runtime) when compared to jQuery.each.

    • Dan Wheeler

      no significant difference in minified, gzip’d bundle – surprisingly close before and after. 

  • http://about.me/JonAbrams Jon Abrams

    CoffeeScript is really fun to write. It has helped me discover the awesomeness that is Javascript by rounding out its rough edges.

    It was definitely a smart move on Dropbox’s part to make the switch!

  • Lucian Hontau

    “We’ve heard many arguments for and against debuggability, and in the end, we convinced ourselves that it’s easy only after jumping in and trying it.” 

    So, in other words, you have only your own opinion and at best one (1) anecdotal experience. Congratulations! You’ve failed to prove your point from a logical perspective, let alone anything more!

    • Ehrlich Bryan

      You can’t prove something is “easy”. It’s a subjective thing. 

  • Anonymous

    Some beef with your little coffee-to-JavaScript comparison chart:

    In the first example the code you’re showing is not equivalent in this context. `BrowserDrag` would have to be equal to `this` for the first example to work, and in that case, why wouldn’t you just use `this`?

    `[].each` is not a thing, just FYI. The method you’re looking for is `[].forEach`, which is ES5 only. Also, you don’t explain (or even bother to show) why `Function.bind` is used here, and why coffee-script doesn’t need to use its fat-arrow binding there. If you want to show iterating over an array, an example that uses a `for` loop would be correct in this caseIt might be a good idea to provide code examples that are **actually** equivalent.

    • Bobo

      [].each is thing if you use prototype js, like Dropbox does. :-)

      • Anonymous

        Might not be a bad idea to mention that, then :D

      • Rick Waldron

        That’s probably why you had so much crummy JS to begin with.

    • Anonymous

      it’s funny how people who use coffeescript always write really terrible js to begin with, it’s a horrid language in practice. I’ve never seen a single coffeescript file that didn’t make me want to rip my eyes out

      • Dude

        Calm down bro.

      • wut

        Slow your roll.

      • http://www.facebook.com/mohamedmansour Mohamed Mansour

        I would tend to agree.

      • http://twitter.com/matjazmuhic Matjaz Muhic

        Agreed.

      • Anonymous

        Not a huge fan of CS, JS when written correctly is beautiful as well

        • Be Rad

          word.

      • http://profiles.google.com/kamil.trebunia Kamil Trebunia

        Exactly.

        Excuse me, but I need to point this out… JavaScript examples are sloppy and inconsistent. Most likely not very thought through as opposed to CS code.

        Especially example #3…

        You guys have 2 different errors (“Object has no method ‘each’” and “Sharing is not defined”), that’s 3 total and unnecessary closure. I assume that ‘Sharing’ in real life was defined before and that ‘each’ is a typo. In that case there are no errors, but then a proper JS code would look like this:

        Sharing.init = function (sf_info) {
          [sf_info.current, sf_info.past].forEach(function (list) {
            list.forEach(this._decode_sort_key, this);
          }, this);
        };Yeah, 5 lines of pretty readable JS code instead of 4 CS lines and most certainly not 9 as you pictured it.Example #2 has unnecessary bind() and example #1… ok, yeah, you’ve nailed some actual annoyance of JS here for real this time :)

        Having said that – for me it’s obvious your CS code is better after full rewrite. But your code would be also better if you would rewrite your JS to JS. Or JS to any other language. Because that’s usually the case when you refactor code.

        So… Nice try CoffeeScript fanatics – still not convinced thought! ;)

        P.S
        I also don’t find CS code readable at all. Especially lack of parenthesis around function arguments confuse me every time I quickly skim through the code.

      • Stefan Mewa
    • Dan Wheeler

      Hey Sam,

      We could have done a better job explaining this. 

      pre-coffee we resorted to a function `each` (added to Array’s prototype) to do for/in iteration over arrays, that takes a callback `function (elm) {…}`. Being a function, the callback re-scopes `this`, hence the bind. (the way we use bind here is similar to the optional context arg in underscore’s `each`.) 

      With coffee, we got rid of the callback via saner iteration, so `this` isn’t re-scoped, and we no longer need a bind/fat-arrow.

      It’s debatable whether an each() helper vs. a normal 3-clause for is cleaner in JS (the first is complex, the second verbose), but we avoid forEach() entirely for the ES5-only limitation that you mentioned.  

      Fair comment about `BrowserDrag` vs `this`. That was something we cleaned up during the rewrite, but was unrelated to JS vs CS.

      take care,
      -d

      • Anonymous

        Sure, those all sound like fair refactors. My only concern was that some of the details seemed a bit off (perhaps because those snippets were shown without some requisite context), and that detracts from the point of showing how coffeescript made the code better or whatever.

        I don’t necessarily disagree that using coffeescript on a large team can help normalize the JavaScript that’s being pushed to production. BUT, personally I find using the straight dope to be more affective, as long as you enforce/evangelize a styleguide among your team. @36c697d974542aadaee06a0f39cb1437:disqus ’s Idiomatic.js ( https://github.com/rwldrn/idiomatic.js ) is a great resource if you want to promote good style without glossing over the details with coffee.

  • Justin Chase

    Both examples appear to fail for the same reason in IE10. Just an fyi.

  • Anonymous

    LOLOLOLOLOL

    • http://twitter.com/justinfreitag Justin Freitag

      tea drinker.

      • Ryan

        Oops. You appear to be cavorting with a prostitute in your profile picture. Did you honestly think that would go unnoticed? Your face says it all.

  • Michael G. Kaiser

    Are you able to share your Selenium fuzz tester? That would be very interesting!

  • Drew

    You guys seriously have nothing better to do than rewrite software that already works?

    • Jon

       this^

      or rather, @^

      • Buh

        Clever :)

    • http://www.datashaman.com datashaman

      Guess you’ve never worked on a mature product before… :P

      • Ryan

        Wow, what a cutting and pithy remark. Especially from someone who’s tagline is:

        “Freelance developer specializing in open-source web development, mostly in Ruby/PHP”

        Trollololol!

    • http://twitter.com/SmokingCrop SmokingCrop

      are you seriously that retarded?

    • http://twitter.com/philippelang philippelang

      Drew, are you a Cobol programmer maybe?

    • http://twitter.com/k_gadek kgadek

      This is the difference between a programmer and a writer. Programmer is a geek, he fixes what is not broken; he’s dreaming and he’s putting his efforts to make dreams come true; he’s pushing development towards future. A writer is a guy who writes/fixes code and… that’s all he’s capable of.

      See http://theoatmeal.com/comics/tesla

    • Anonymous

      this calls for: http://www.youtube.com/watch?v=WiJczH3cr48. “… optimize the things I’ve always had…” ;).

    • http://edditoria.blogspot.com/p/about.html Edditoria

      That may becase

    • http://edditoria.blogspot.com/p/about.html Edditoria

      It will be worth to do so, if they have a plan for expansion, and/or reduce cost of maintenance!
      Sometimes you may want to start-over when you know it will become a mass.
      Pro-action is a must for real business (not only because a geek)

    • Dru

      Drew, 
      Are you a Chef ?

  • http://twitter.com/justinfreitag Justin Freitag

    if you like coffeescript you might like coco…more.

  • http://jongleberry.com/ jongleberry

    first code, you can just use a try catch statement instead of going through each level of attributes.

    for the second and third, you should be using `.forEach()` not `.each()` unless you’re doing something silly, and you should really be comparing apples to apples. Comparing `.forEach()` to `for` is quite different.

  • threedot

    CofeeScript really have got good features. But follow the code flow very hard with CofeeScript.

    I can follow the code flow with matching brace on JavaScript easily. I don’t like whitespace indentation to collapse statements instead of curly brace.

    These days I’m trying to google’s traceur compiler.

    http://code.google.com/p/traceur-compiler/

  • http://almirfilho.com/ Almir Filho

    Just awesome!!!
    Dropbox is a beautiful service now with a beautiful code.

  • 77luckyguy

    I think alot of you missed the point of the article…the right tool for the right job

    • Brett Aquila

      Which job would that be? The job they couldn’t do with javascript? Nope. The job of making their product better? Nope. Oh yeah, the job of re-doing what was already done. It’s like unscrewing a screw, changing screwdrivers, and screwing it back in. In the end, you have exactly the same finished product you started with, you just used a different tool to put it back together after you pulled it apart for no reason. 

      • http://twitter.com/JakeHoffner jake hoffner

        The point was that they want to write all new code in coffeescript so they needed to convert the old code first. Otherwise it would be like needing to always have two screwdrivers with you when you only should need one.

        • http://twitter.com/matti_sg Matti Schneider

          I guess the question skeptics ask here is: what was so wrong with the original screwdriver that couldn’t be fixed with a one-page manual and a half hour lecture to all team members?
          Were the tool’s limitations really so big that they justified such an investment to switch to a new screwdriver?

          Wasn’t it simply that the handle of the newer screwdriver felt so sexy that it was forgotten one screws with the tip?

      • Clint

        I think one of the points is that you can write CS faster than JS in some cases. Less characters to type means faster code. But it also allows you to be future proof. CS will compile to the latest supported javascript language constructs for you, so no need to update in the future. What I am saying is, they didn’t switch to CS to make their software better right now, they did it so it will be easier and faster to make it better in the future.

        • http://twitter.com/matti_sg Matti Schneider

          …and probably spent more time doing so than updating their existing codebase for the foreseeable future. One week full time for the whole team, nonwithstanding bugs uncovered later, represents quite some time.

          > “CS will compile to the latest supported javascript language constructs for you, so no need to update in the future.”
          Well, unless you can decide that you support only ES6 browsers, which of course very few people can, and I guess not Dropbox, there’s really no point in this. You’d be better off with a clientside library that can indeed update, not language constructs, but DOM API calls, to their latest version dynamically, based on browser support.

          Anyway, authors: thanks for sharing your impressions, and congrats on the job! I am not convinced this was the most productive task, but managing your own time is entirely up to you, and I didn’t see that you advised others to convert their whole codebase immediately. So, thanks for your experience!  :)

  • http://twitter.com/routecpt RouteCaptain

    FYI – the new CoffeeScript complier supports source maps:
    http://ryanflorence.com/2012/coffeescript-source-maps/

  • http://twitter.com/bevanhunt Bevan Hunt

    FYI – CoffeeScript supports source maps:
    http://ryanflorence.com/2012/coffeescript-source-maps/

  • http://twitter.com/ysaw Stephen Woods

    With all due respect (I think we saw you guys at Naked Lunch once), you took a bunch of code that works, but you didn’t like the syntax, so then you rewrote it?

    • Brett Aquila

      That’s what I gathered from it. Either you and I are idiots because we don’t get it, or they’re idiots for re-doing something that was already done. It’s like taking off your pants, changing your underwear to a different color, putting the same pants back on, and shouting “Look at me now!!!!” What’s the point??? I don’t see the difference. 

  • http://wilmoore.com/ Wil Moore III

    Interesting article. Many of your points are well-taken; however, I’ve actually found that the CoffeeScript syntax starts to get in the way when writing larger apps. I don’t mind it so much on smaller apps. 

    That being said, I’m glad it worked out for you.

    • Anonymous

      yeah, and using a less verbose language doesn’t help your application size problem.. modules scale, language tokens do not

      • http://wilmoore.com/ Wil Moore III

        Exactly…and this isn’t the case only with JavaScript. It applies to pretty much every language I can think of.

        • Anonymous

          yup, plus the verbosity of some js tokens are a benefit, when I look at coffeescript you have to read very careful to pick out each ambiguous token, not something I would consider to increase productivity, nor is it beautiful it’s just a sloppy mess of words

  • http://gplus.to/mrgenixus Benjamin West

    Hey Congrats on what sounds like a *tremendous* code review! Looking forward to more consistent user experience.  

    I’d like to make a couple of points that I didn’t find in the existing comments:

    1) I think whether you’re using coffeescript, underscore, backbone, or YUI, using a language that deals with scoping and builds concise idioms for functional coding problems is great; I’m not sure you can really treat coffee script any different than any other library.  I think that using a library is great

    2) A Colleague and longtime JavaScript-er has recently switched to Coffee Script; I think that’s great because it makes him marketable to YET another small subset of companies using something a little bit off of the beaten path; For all the people out there who are determined to hate on Coffee Script: We know you were into JavaScript before it was cool, but, even if Coffee script is ‘just-another-fad-language,’ People are using it.  Learning it improves your opportunity for hire.
    3) Using Coffee Script opens up a lot of opportunities that only real engineers would consider: Some idioms in Javascript run faster on Node and it some byte-code oriented browser interpreters.  This gives code that favors those idioms a way to run as fast as C code.  When you write coffee script, you give yourself the ability to pre-select for those idioms, and really allow your code to have superior performance.  Leverage compile time, if you have compile time, anyhow.

  • Anonymous

    hubot image me @coffeescript++

  • http://twitter.com/PragTob Tobias Pfeiffer

    Thank you very much for this post with lots of background information! Cool that you made this step =)

  • http://paulmillr.com/ Paul Miller

    haters gonna hate

  • Meg

    this.originalStyle = {};
    ['top', 'left', 'width', 'height'].each(function (k) {
    this.originalStyle[k] = this.element.style[k];
    }.bind(this));What on earth is this for? Without context, it worries me that you might be doing things that would be far better done in CSS

  • Prathmesh

    I made up my mind that I will read the entire post but couldn’t help myself scroll down and comment, and thereafter close the page, I hope.

    I code sometimes and I certainly agree with Ryan Florence’s conclusion. CoffeeScript might be easier to read but JS is way easier to comprehend. I believe the reason is the way we all learned programming. “, ;, {}, ()”  are not syntactic noise(as u claim), they are the syntactic sugar/honey, indeed.

  • Akm 14889

    useless overwrite i must say 

  • Anonymous

    Its strange you’re showing the “numbers” and stuff from the .coffee files, and not the one with the .js generated from that files … guess what will happen with that “beautiful” JS :D)

  • Chris R

    The way I read part of that: 

    “Some people say CoffeeScript is just syntactic sugar and a coding style preference. We think that is ridiculous. To prove that, take a look at this syntactic sugar CoffeeScript gives you! Great, eh?”

    Absolutely not convinced CoffeeScript is any improvement after reading this…

    • Brett Aquila

      Leaves me with the exact same impression I’ve had about CoffeeScript from day 1 – looks different, adds nothing. 

  • Anonymous

    I’d love to see CoffeeScript or some other language in the browser, but since deciding and implementing one language in every browser would take decades, I think browsers should add something like Perl 6′s Parrot or Java’s VM technology.  That way you could build languages on top of the VM and people could code in whatever they like.

    • Craig

      I’d love to see a language specifically designed to be a compilation target, so we could stop being forced to use languages from design-by-committee, academic fucks.

  • http://twitter.com/gnuwilliam William Oliveira

    Revolution is my name

    • Ryan

      Please shut up.

  • http://twitter.com/gnuwilliam William Oliveira

    Revolution is my name

  • Evan

    That’s it, I’m switching to Google Drive.

    • http://www.epicserve.com/ Brent O’Connor

      Because Google doesn’t do any compiling into Javascript tricks. Not! (https://developers.google.com/web-toolkit/overview)

      • Craig

        Google do it because they consider it easier to write static analysis tools for languages with static typing. Dropbox do it because they’re Hipster Hackers.

  • http://twitter.com/gnuwilliam William Oliveira

    What if I told you… http://bit.ly/OuHVHD

  • Anonymous

    21% LOC saving with worse readability to those accustomed to JS syntax does not seem worth arguing for

  • http://twitter.com/chester89 Gleb Chermennov

    awesome! I think CoffeeScript is the way to go, not JS with it’s crappy syntax and braces

  • http://twitter.com/jakemauer Jake Mauer

    Could you elaborate on your server side compilation setup? I’d love to implement that on my projects. Currently I pre-process using Guard and deploy the pre-processed files.

    • http://www.epicserve.com/ Brent O’Connor

      Unsubscribe

  • Pierre

    This is great! And I look foward to Dropbox’s code contributions to the community.

  • http://thoughtresults.com/ Saeed Neamati

    Lesser lines of codes doesn’t count for goodness or superiority of a framework.

    • Craig

      The term “superiority” is pushing it a bit, especially for web development, an “industry” that mostly specialises in concatenating strings.

  • Charlie Magee

    From a beginning coder . . . I struggled for weeks with javascript. Most of my errors came from missing or misplaced ) or } or ;. What a waste of time. Then I tried coffeescript. My errors dropped dramatically and immediately, and the speed of my learning how to write code that actually did something useful took off.

    • Craig

      And later you’ll realise that syntax is far less important than semantics and that both JavaScript AND CoffeeScript are appalling languages by which to learn Computer Science or Software Development concepts.

  • Nico Sap

    What would have been the difference between Javascript and Coffeescript when both scripts where minified at the end?

  • DB-Fan

    the CoffeeScript syntaxe is very bad… and wow you saved thousand of }-lines… unimportant

  • Doeke

    Never looked at alternatives; think Google’s Dart?

  • http://roadha.us/ haliphax

    “Automatic semicolon insertion woes” — I have never, and will never understand this argument. If you’re using semicolons where you’re supposed to, instead of trying to be tricksy and hip, you will literally NEVER run into this problem.

    • Pierre

      I doubt that you’ve never forgotten to add a semicolon to a statement. The problem is that the resulting errors are often unpredictable. If JavaScript just threw an error or warning when a semi-colon was missing e.g. “Error: line 2 is missing a semicolon”, it would eliminate the problem altogether. Adding a semicolon is just plain sneaky.

      • http://roadha.us/ haliphax

        True dat.

    • Craig

      Lua doesn’t require semicolons either, by virtue of the grammar not requiring them at all, as opposed to nasty hacks like ASI. You can literally write a Lua program on a single line (bad idea obviously, but possible). That’s the way a grammar should be. They used ALGOL style syntax where appropriate but fixed all the mistakes and parts poorly suited for a dynamic language. JavaScript just copied C and Java syntax wholesale and added a whole clusterf*ck of new mistakes (regex literals — WTF?!).

      • Craig

        *on a single line without statement separators…

  • http://twitter.com/mattdbridges Matt Bridges

    From what I’ve gathered, it certainly seems like there are rabid opinions on both sides.

    Fact is, some of us like the simplicity of writing in a beautiful language like CS. JS to me has always felt bloated and annoying to deal with. Granted, I’m no JS expert, but after writing CS and looking at the JS it compiled, I’ve learned a TON about the language I was always afraid to learn.

    I think a huge reason re-writing code that already works does two things: 1) It solidifies in the developers minds exactly what that 23,000 lines of code actually does (apart from reading tests). 2) It gives them a chance to optimize and find better ways of doing what already works better and faster.

    Personally, I write a CS class in about a fraction of the time it would take me to write a JS “class”. And it would be shorter and easier for me to read. But again that’s just me.

    Yeah, yeah, flame away…

    • Andrew

      You learned a TON about the language you were afraid to learn? Sounds like you seriously need to sit down and get to grips with JS before giving it up for something else. Syntax is just syntax. Become fluent, learn the idioms and code away. When you speak English, do you say “oh no, English has too many verb conjugations, I think I’ll learn Japanese instead.” No? Didn’t think so.

      • LoveIsWealth

        stop trolling.
        why would he need to sit down and ‘get to grips’ with JS? CS works well for him and he’s able to debug in JS whilst learning the language to boot. the japanese/english example is a terrible metaphor.

        i’m waiting for a better language, but until that coffeescript makes JS programming bearable. i’d be willing to consider something like kaffeine, wherein JS syntax is all still valid, but CS provides ample utility justifying its use.

  • Aaron Sherman

    JS/CS wars remind me of Emo’s routine about religion… as soon as someone does something slightly different in a subculture, the subculture turns on them as if they had no common ground whatsoever…

    https://plus.google.com/u/0/108373812962355405651/posts/eSfVmnwnA5w

  • http://twitter.com/hij1nx Paolo Fragomeni

    For history’s sake, Tim Caswell (@creationix) created Coffeescript and Jeremy Ashkenas is the maintainer. It’s not obvious to noobs, but Coffeescript is pure programming masterbation.

    • Craig

      Both of those guys are noobs — i.e. front-end hipsters who specialise in new and novel ways of concatenating strings.

  • http://twitter.com/hij1nx Paolo Fragomeni

    For history’s sake, Tim Caswell (@creationix) created Coffeescript and Jeremy Ashkenas is the maintainer. It’s not obvious to noobs, but Coffeescript is pure programming masterbation.

  • Michael Calkins

    Can we see your Seleniumhq test code?
    This random walk would be incredibly to test my sites with.

  • http://twitter.com/Endophage David Lawrence

    Just felt like pointing this out: LOC is widely recognized as a poor indication of anything about your code other than how many LOC it is…

    Secondly, I can write code with very few tokens, it is less readable than code with a sensible amount of tokens.  Calculating intermediate values and assigning them to named variables can make algorithms significantly easier to understand.  To that point, token count is also a very poor indication of code complexity.

    I’m trying to come round to coffeescript but I have trouble when I reach real world code and see terrible Frankenstein code.  Examples are all good and well but maybe somebody can point how to me how to write this (jQuery based snippet) better:

    $(‘#someDiv’).html “”"foo”"”

    It seems that method chaining in CS, a very useful feature in many many languages, requires you to write a mix of CS and JS syntax.  I’d be very interested in knowing if there is a better way to do the above, and say, what if I wanted to write in CS the equivalent of $(‘#someDiv’).show().html(“foo”).  This mashup of syntax really puts me off and is just about the ugliest thing I’ve ever seen.

    • Craig

      SLOC says nothing about code quality or complexity but it says enough about how much time you’ll have to spend reading any given piece of code to go back and update/maintain it. Anyone who says SLOC is meaningless has a severe lack of appreciation for subtlety (read: is probably a very poor programmer).

      • http://www.facebook.com/dclwrnc David Lawrence

        That’s why I said it’s a “poor indication” as opposed to “meaningless”. If LOC is all you have to go on, you know nothing (other than LOC).

        That being said, if two pieces of code _in the same language_ do the same thing in a different number of lines, the shorter one _may_ be better (bearing in mind it’s easy to reduce LOC by not doing intermediate assignments but that may make the code harder to understand).

        The difficulty with comparing two different languages (coffeescript may compile to javascript, you can compile C to Assembly, you would never say they are the same language), is that languages are inherently different.

        I can write a Python application and a C application that do identical things, the Python version will be many LOC shorter. Does that make the Python application “better”? Absolutely not.

        Coffeescript introduces some syntax common to functional languages, particularly list comprehensions, which are inevitably going to significantly reduce LOC. Do they make the code more readable? *shrug* I can read a for loop fine and I really don’t feel it takes me less time to read a list comprehension.

        I don’t think my post particularly bashed coffeescript and I asked if anyone knew how to do method chaining, the thing that really annoys me in coffeescript. Thanks though for trying to disparage me (and posting anonymously to boot). Anyone who says shorter code is, by default, easier to update/maintain has a severe lack of appreciation for subtlety (read: is probably a very poor programmer).

      • http://www.facebook.com/dclwrnc David Lawrence

        I should also point out you contradicted yourself in your first sentence. “code quality” and “complexity” are the two most important factors in how long you’ll have to spend reading, updating and maintaining code. By your own hand, LOC doesn’t tell you anything about those things, therefore, LOC really doesn’t tell you anything about how long you’ll have to spend reading, updating and maintaining the code…

  • http://twitter.com/Endophage David Lawrence

    There are meant to be <p> tags around those “foo”s above but they weren’t escaped and editing appears to be broken (just get a “something went wrong” message, guessed you missed that when you were testing your cofeescript move).

  • http://twitter.com/stephenhandley Stephen Handley

    I like a lot of things about CoffeeScript but it took certain things too far. The following make CoffeeScript code significantly more readable in my opinion

    1) Don’t consider parens as optional for method invocation
    2) Don’t consider { } as optional for object literals (aside from when faking keyword args)

    I suspect those two style options are a source of a lot of the fudhate from the js community.

  • Pingback: Quora

  • http://abraxas-online.com/ Abraxas

    its code compilled on client¿

  • Chris
  • Andrew

    So……….. you moved to CoffeeScript to save on keystrokes? Because that’s what your argument is about. Not to save on disk space (actually disk consumption will probably expand). Not because CoffeeScript is easier to learn, because a CoffeeScript expert should know JavaScript too. Not because CoffeeScript is more powerful, because whatever CoffeeScript can achieve, can also be achieved in JavaScript, by definition. Not because CoffeeScript has better support, because clearly it doesn’t, either in terms of tools, resources and support. But to save on keystrokes. The fact you wrote this article in a defensive manner shows you doubted it was the right thing to do.