6 ms·
A CoffeeScript Intervention
- Seldaek 15y agoI don't quite agree with the conclusion of the article ("you’ll come away with a better understanding of JavaScript"). The fact that CoffeeScript hides scoping and other stuff from you means you will never have to learn how JavaScript really works. You can argue whether this is good or bad, but it's not giving people a better understanding of anything, it's just making them follow best practices unknowingly.
- TrevorBurnham 15y ago(I'm the author.) JavaScript can be pretty overwhelming to newcomers. You mention scope, which is a good example of where CoffeeScript actually clarifies rather than hides the underlying semantics. The most important thing to understand about scope in JS is that only functions create scope. This is very different from C and Java, and since JavaScript looks like C and Java, that difference is surprising (see e.g. http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-...). When you learn the same rule in CoffeeScript, it feels a lot simpler. And that understanding can carry over to JS. Granted, the compiler is generating the `var` keyword for you, but the mapping is trivial. What's important is that scoped variables have the same behavior in both languages.
- Seldaek 15y agoAll I'm thinking is that people should start using JSLint instead of making up languages on top of JS. That will catch most of the bugs due to common misunderstandings of the language.
- technomancy 15y agoJSLint can't solve the "I forgot to include a frickin' explicit return again" problem, can it?
- Seldaek 15y agoThat's a first world problem of ruby devs I think. When you're used to it, you never forget to write return statements.
- Confusion 15y agoRuby is far from the only language that is commonly used without explicit return statements (and it at least has them). It's just currently the most popular one.
- rubergly 15y agoAgreed. I hardly think that people who haven't used languages like Ruby or Coffeescript (with implicitly returning the last expression) ever forget return statements in a way where everything would be okay if they just added a "return" keyword. When I use Ruby and Coffeescript, I consciously have to think "no, I _shouldn't_ write return this time"; I find it hard to believe that, without using a language like this, anyone would just write an expression and expect it to be returned. I could see an argument that if you're returning the application of a function, but it has always seemed extremely natural to me that I think about what I'm returning when I write a function; I actually always have a little bit of trouble adjusting to writing Ruby-style return-less code.
- rawsyntax 15y agoit depends on how you think of functions... If you think of everything as an expression, of course it has some kind of value. That being said I prefer not to have to write "return" but work plenty with languages outside of ruby and have no issues writing return when necessary.
- technomancy 15y ago> it depends on how you think of functions... If you think of everything as an expression, of course it has some kind of value. Sure, and functions by definition return a value. I know programming isn't math, but the notion of a "void function" is somewhat of an oxymoron.
- deleted 15y ago[deleted]
- vijaydev 15y agoNice article Trevor. But you could have avoided the last statement creating unnecessary FUD in the minds of Rails users.
- TrevorBurnham 15y agoHa, yeah, but I did want to mention the Rails 3.1 support somewhere (a vote of confidence in CoffeeScript from the highly respected Rails team); given that, a link to http://doihavetousecoffeescriptinrails.com/ http://doihavetousecoffeescriptinrails.com/ seemed the best way. Rails people have a good sense of humor. I hope...
- telemachos 15y agoThis is tangential to the main thread, but the weirdness that is hoisting surely confuses a lot of people. (To clarify: hoisting seems to me to be more or worse than just "there's no block scoping.") Just now on my the subway ride home I came across this example from David Flanagan's JavaScript: The Definitive Guide: var scope = "global"; function f() { console.log(scope); // Prints "undefined", not "global" var scope = "local"; // Variable initialized here, but defined everywhere console.log(scope); // Prints "local" } I'm someone who uses Javascript only occasionally, and I'm trying to learn it better. But I thought I understood scope just fine: no block scope, function scope, lexical scoping within functions and nested functions. I may have read about "hoisting" before, but honestly it never sunk in until today. So I'm assuming that Coffeescript always compiles down to Javascript where variables are explicitly hoisted upwards in declaration? (Answer appears to be yes from a few quick tests here...)
- podperson 15y agoI don't see how adding a completely different syntax layer and compilation makes coding in JavaScript less overwhelming. Using jslint eliminates item 1. Item 2 is a stupid language quirk. Guess what, Coffeescript is a whole new layer of quirks. Aside from item 4, the rest are based on a mistaken idea that reducing typing somehow is a huge advantage. (I don't know, it may be for some people but I'm either too fast a typist or too dumb a programmer.) CoffeeScript is probably very appealing to some people because it imports coding conventions from some other language (Ruby I guess) that they like. I happen to like JavaScript and running code through jslint once in a while is a heckuva lot less annoying than having to compile code and deal with debugging "assembler".
- lucasr 15y agoThis is why I think 'let' pretty much fixes (or maybe sanitizes) scoping in JavaScript (see e.g. https://developer.mozilla.org/en/New_in_JavaScript_1.7#Block_scope_with_let_%28Merge_into_let_Statement%29 https://developer.mozilla.org/en/New_in_JavaScript_1.7#Block...). In summary, it allows you to define variables per block. Unfortunately, it's a feature only available in Mozilla's JS engine at the moment.
- oinksoft 15y agoIf you can't be bothered to learn the behavior of keywords as fundamental to JavaScript as "var" and "this," then yes, you'd better be using some wrapper. Items (3) and (5) seem to be the only valuable features demonstrated here, and (5) should be present in the ES Harmony (it is already present in JS 1.7). The article states that > It’s about more agile code but I find this claim dubious when the best JS tools are for JS, and not CoffeeScript. I believe that the features provided by the Closure compiler are more beneficial for stable JavaScript development (annotations, etc), and carry a significant performance incentive.
- raganwald 15y agoWithout agreeing or disagreeing with your conclusion, I'm not sure I understand what you're reaching for with the opening sentence: If you can't be bothered to learn the behavior of keywords as fundamental to JavaScript as "var" and "this," then yes, you'd better be using some wrapper. That seems to be trivially true, but in context it only makes sense if you're implying a bi-conditional, namely that the only reason to use a wrapper is if you don't understand var and this. I believe that to be false. There are many reasons to use syntactic or semantic sugar even when you understand the underlying language very well. As a demonstration of this, I give you that most tools of this type are written by people who understand the underlying languages incredibly well and design such tools for their own use as relative expert users.
- oinksoft 15y agoOh, I just meant that those (confusion with `this` and `var`) were pretty silly things to point to in praise of CoffeeScript, as they are so easy to understand and fundamental to JavaScript. Like you said, CoffeeScript is aimed at a broader audience than those who can't grasp JS basics.
- jacobolus 15y agoThe problem is not confusion about them, or inability to figure them out, per se. Dealing with syntactic awkwardness and features full of tricky corner cases takes mental effort even if you can understand them perfectly. Coffeescript let you (to a greater extend than JavaScript) write and read just the code you mean, without having to think explicitly about these questions every time. You still have to understand JavaScript in a fairly deep way to build solid CoffeeScript programs.
- hasenj 15y agoInteresting. I didn't know about the 'do' keyword or the repetition bit with {x,y} returning {x: x, y: y}. Pretty cool!
- tomstuart 15y agoThe {x,y} rvalue syntax isn't in the CoffeeScript documentation. This is the first place I've seen it.
- grayrest 15y agoIt was but it got dropped in the doc update for 0.4 or thereabouts. I was hoping he'd take it out for a while because it complicates the disambiguation of braceless object literals but it seems most people like it, so meh.
- tomstuart 15y agoIt's a bit weird that it breaks alpha equivalence (i.e. you expect your program's semantics to be invariant under local variable renaming) but I can see why people like it. It's certainly compact and idiomatic, and there's a nice (albeit superficial) symmetry with destructuring assignment.
- jasonkester 15y agoWow, this article actually had the opposite of its intended effect with me. I had always expected that CoffeeScript was a better form of JS that I should probably get around to learning. Now I've just learned that besides having an unpleasant syntax, it actually redefines some important features of javascript to behave in novel ways. As an example, the whole point of setTimeout is to be able to do the sort of thing shown in Example 4. Defeating it just means you now have to search for another way to do the things that setTimeout was designed for. Same with variable scope. If you can't declare a global without actually standing in the global scope, that makes things harder, not easier. Beyond that, I glazed over at seeing various little ascii arrows. I'm sure they're there for a reason, but by then I was already halfway out the door.
- jacobolus 15y agoFirst, use or don’t use what you want. If you don’t like the cleaner CS syntax, stick to writing raw JS. Your other points aren’t especially valid though: 1) You can trivially use setTimeout just as you did before. CoffeeScript just gives you a couple extra tools for simplifying things when you have use cases like the one presented in the article. 2) As for the global namespace: if you want to attach something to the window object it’s much more readable to just write "window.foo = bar" or whatever. In general though, I defy you to come up with an example where you want to define global variables from some other scope where your code wouldn’t end up just as clear but more robust with cross-scope variables defined in some high-level scope. Pretty much everyone agrees that JavaScript’s "pollute the global namespace by default" feature was a mistake. The ascii arrows are by far the best part. JavaScript turns out to be a very nice language (semantically) for writing functional-style code. Unfortunately, the regular JavaScript syntax makes defining functions so unpleasant that I go out of my way to avoid extra ones. CoffeeScript makes defining functions so easy that I go looking for ways to use more, instead.
- bergie 15y agoIt looks like the future of JS resembles CoffeeScript quite a bit: http://brendaneich.com/2011/05/my-jsconf-us-presentation/ http://brendaneich.com/2011/05/my-jsconf-us-presentation/
- beseku 15y agoThis and the recent release of 1.1.0 gave me a push and I spent some time converting a small library I maintain (http://flickrshow.com http://flickrshow.com) to CoffeesScript as an exercise and and education into the syntax and potential benefits. As it was a 1-1 conversion it was fun to see not only how much syntactical cruft the CS syntax removes but also how a few sloppy lines got tidied up, (mainly existence checks). In that sense, it adds value. It'll be interesting to follow this up with how easy it is to churn out new code ...