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.
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.
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.
"Stop hitting yourself with a hammer."
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.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?)
For example:
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:
Instead of the far more efficient: 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. Ping me the next time you're in NYC. Always happy to grab a drink and talk shop.