Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This essay is fairly amazing -- there's so much emotion and so many assertions packed into it, and yet they're all founded on innuendo and hearsay, not on how things actually are. Most of the things Leon writes are factually incorrect, but at the same time, you can see how listening to enough FUD might make you start to think them...

For example:

    > CoffeeScript classes have attributes and properties that 
    > are encouraged to be mutated by reference so a language 
    > contrivance was devised (@) to allow OO style encapsulation 
    > while still trying to provide Functional referential 
    > transparency in anonymous contexts… wrap your head around that.
What? Instances of CoffeeScript classes are just like any other JavaScript object with a prototype -- just like any old string or function or array. The "language contrivance" `@` symbol is simply an alias for `this`. Nothing more and nothing less. `@name` in CoffeeScript is just `this.name` in JavaScript -- I'm not sure how you wind up with "functional referential transparency in anonymous contexts" from there ... but I'll have a little of whatever Leon's smoking ;)

There's many other things in the essay, but the core boils down to this: There are a bunch of folks who are used to ignoring prototypes in JavaScript because they hand-roll objects by manually adding properties or using Crockford's "module pattern". For them, CoffeeScript's `class` keyword feels like it's adding something alien to JavaScript because it makes prototypes accessible. It's not. Using prototypes and objects lies at the core of JavaScript, and it's only the difficult and fragile syntax that leads people to manufacture new instances like this:

    var makeDog = function() {
      return {
        bark: function(){},
        run: function(){},
        ...
      };
    };
Instead of the far more efficient:

    new Dog;
Finally, CoffeeScript isn't encouraging you to do anything in particular. If you truly don't like using prototypes in JS, feel free not to use `class` in CS.

    > Jeremy Ashkenas, whom I do not know but would 
    > LOVE to have a drink with (alcoholic drink or 
    > otherwise) and pick his brain ...
Ping me the next time you're in NYC. Always happy to grab a drink and talk shop.


Did HN's "no editorializing the original title" policy change, or does it go absent on Fridays? How did "My Perception of CoffeeScript" get changed to "Finally, an objective and balanced look at Coffeescript vs Javascript"?


Woo, it has been fixed. I was going to suggest flagging it for that reason :|


This post doesn't make much sense to me either. JavaScript encourages an object-oriented style, but with prototype-inheritance and flexible method binding (where `this` in a function is determined by the caller). CoffeeScript's features embrace both of these design choices and make them easier to use. Using the `class` keyword to set up a prototype chain is really nice, and `@` opens up whole new possibilities that would have been too syntactically heavy with the `this` keyword.

JS is object-oriented. If you really want to write functional code in JS, you're going to need persistent data structures, like Clojure (and presumably ClojureScript) provide. Otherwise you'll pay a high cost for constantly copying objects. Without persistent data structures you pretty much need to mutate properties to remain performant. And if you're mutating properties, object-oriented code is a good approach.

I don't understand why the author sees randomly assigning functions to anonymous objects as a superior approach to using prototypes.


Nice to have you chime in here Jeremy. I personally use CoffeeScript a lot. I also code in Ruby and understand its appeal from that perspective. However I am curious what your take is on dxbydt's reply below. He makes a very interesting comment about the overhead of objects vs simple message passing/currying/etc.


My take is that it's a classic straw man -- you can write inefficient functional code that constantly manufactures and throws away closures ... just as easily as you can write inefficient object-oriented code that constantly manufactures and throws away objects.

The point of object-orientation is that "simple message passing/currying/etc" rarely stays simple for long. Eventually your system wants to have many different pieces of data that all share common functionality, and objects are a great way to model that. But if you prefer to work procedurally, and have a big data structure and a bunch of little functions that operate on it -- that's fine too. CoffeeScript and JavaScript support both.


> "you can write inefficient functional code that constantly manufactures and throws away closures ... just as easily as you can write inefficient object-oriented code that constantly manufactures and throws away objects."

Very true, except that it doesn't happen in practice.

There's a more elaborate discussion in Joshua Suereth's book "Scala in Depth" on this very topic, because Scala has the exact same problem. A boatload of OO Java guys are now migrating to Scala, bringing their OO with them. Teaching them Scala is trivial, teaching them FP is not.

The example Joshua gives is "a cat catches a bird and eats it".

How should programmers model that ?

What programmers should do is focus on the verbs. So first define a catch function and an eat function. Then compose them like this: catch(...) andThen eat(...). Define a Cat trait and a Rat trait & you are in business.

What most programmers will do is focus on the nouns. So they will first define a class Cat {} with two methods catch() and eat(), then a class Bird {}, then wonder about whether there must be some class Animal {} which Cat & Bird must inherit from, except that birds aren't really animals, so...finally they'll create a cat object and a bird object and call cat.catch(bird) and then cat.eat(bird). When the program runs, there'll be many cats & many more birds & all these little objects will unnecessarily bring things to a crawl.

This has nothing to do with CoffeeScript the language, which ofcourse supports FP as much as it does OO. Its just that in practice people latch on to the OO aspects of CoffeeScript because that's just how most people process problems.


"Doc, it really hurts me when I hit my hand with this hammer. What should I do?"

"Stop hitting yourself with a hammer."


I note the same in another part of this thread, showing how you can write his JS in less CS code.

However, I'd argue that the reason most people are adopting CoffeeScript is for the "class ... extends" as it lets them model their JavaScript code much like they might have in their old Java, and more likely, PHP projects. And once you throw that out, the main draws remaining are default argument values, string interpolation, and the ? operator.

The question is, do those benefits warrant the added layer of complexity? Many of us who have worked with JavaScript for a very long time wonder about this, and dread the deeply nested class hierarchies we might encounter in CS projects because CS makes that so _easy_ to do. But bad programmers will write bad code in any language, and I hate to think what a dev who uses `class ... extends` as a crutch would write in plain JavaScript. So, I have both positive and indifferent feelings about CoffeeScript, the only negatives being with the handling of variable scope/shadowing, which is of course opinionated and neither right nor wrong, and the parser itself which makes for ugliness like

  window.addEventListener 'load', ->
    # Do stuff ...
  , false
  # leading comma is needed above.


the only reason i use CS is because I can get away with typing way less than needed. There is a one time cost (huge? or not!) for setting up tooling to compile it automatically.

If not anything, typing is the only reason I love CS. Because studies have shown (anyone got links, i know them from greg wilson's talk from CUSEC)

1) Less lines of code - less mistakes

2) You produce same number of lines of code, no matter the language

and (not related to studies) 3) less lines to debug 4) if you can deal with the idiosyncrasies of JS, that person can deal with CS quite well. (stawman argument anyone?)


I don't know about most people, but I use CS a lot and never use classes... :)


Might be worth noting that this post is 8 months old.


Hey Jeremy! On a totally unrelated note, if I only have 48 hours to spend in New York city, what would you suggest I visit?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: