Some nice examples, if a bit unfair since the JS is clearly compiled from the CoffeeScript rather than hand-coded. In fact, the last example reveals a bug in CoffeeScript—the function
(x, y) ->
for game_piece in @game_pieces
if game_piece.is_at x, y
@held_item = game_piece
@held_item.start_dragging x, y
break
Notice that _results is initialized as an empty array... and is never modified, making it an utterly pointless return value. What's happening is that the CoffeeScript compiler has both implicit returns and list comprehensions, which means that it tries to return an array of all the values in the loop. All well and good, but the compiler doesn't try to do a list comprehension when there's a break... and yet it creates the frivolous _results variable anyway.
Obviously I'm a fan of CoffeeScript; this is a minor bug and I expect it to be fixed. But let's be fair in making the case for it. Well-written JavaScript will always look better than CoffeeScript output; it just takes a lot more work.
When you directly compare coffeescript to JS and looking at more or less the same code (but of course it's very unfair to JS to use coffee compiler output instead of hand written JS), you won't find much of a difference aside of the small syntax changes.
But once you are used to coffee, your code will start to look very different from pure JS code. Coffe encourages you to write even more, even smaller functions due to its lean syntax.
This new coding style that emerges (at least it began to emerge for me and a coworker) is infinitely more readable than JS, even more so when you look at a direct translation.
My takeaway from this is two things:
1) coffee is cool. Just give yourself one time to adapt. At first everyone's code in $NEWLANGUAGE looks like code in $OLDLANGUAGE until you get used to the common idioms in your new language.
2) The general syntax of a language can have a huge effect on your code style which in turn can have a huge effect on overall readability.
I haven't seen that yet but I can imagine it happening. I love Javascript but coding lambdas always felt ugly enough that I used it more in C# than JS. It is definitely true CS fixes that for me.
At least for the first example, the reason the JavaScript code is so bad is that the CoffeeScript code is equally bad. It repeats an entire for loop for each character code!
Having a concise syntax doesn't relieve you of the duty to simplify your code. Both the CoffeeScript and JavaScript code can be simplified considerably, as several others have pointed out.
In fact, if you clean up the CoffeeScript code like this:
I find CoffeeScript pushes programming in the browser over the crucial tipping point between Not Fun and Fun. (I'm almost embarrassed by how much of a sucker I am for syntax, but there it is).
> I'm almost embarrassed by how much of a sucker I am for syntax, but there it is
It's interesting how so many people profess love for CF's syntax, where I have such a dislike for it (to me, it looks like a magpie language: rather than a whole design it's cobbled from shiny pieces taken from all over the place; the way some features are "integrated" are close enough to yet far enough from the source language that it lands straight in my uncanny valley; it's drawing back from the OO/Func movement of the JS community back into procedural and statements-based something fierce; the target language leaks heavily through such things as the thin v fat arrows; and finally it draws back from things I think are genuinely better features of javascript, such as explicit scopes)
> it's drawing back from the OO/Func movement of the JS community back into procedural and statements-based something fierce
This statement is completely incorrect, the truth is actually the exact opposite.
First I would note there is no such thing as a statement in Coffeescript. Everything is an expression ... this may seem like a minor point to some, but it's actually quite a powerful difference. As with a lot of the things CS adds, It's hard to appreciate the boost in expressiveness until you start writing a lot of code with it.
If you want to talk about functional programming, expressions rather than statments count as 1 whole point out of 9 for PG's "list of things that are awesome about lisp".
Another important aspect of functional programming is lambdas, JavaScript does not have "real lambdas" because of the lack of implicit returns and the aforementioned quality.
By adding them, CS get's you much closer to real lambdas. This combined with the light syntax for functions encourages one to program in a much more functional style.
These qualities enable say, quick and easy decorators:
logged = ( f , named_f ) ->
if named_f? then [ f, name ] = [ named_f, f ] else name = "function"
# decorated function, to be returned
( args... ) ->
console.log "#{name} (#{f.length}) with #{args.length} args."
f.apply @, args
# random function, note our decorator preserces "this"
foo = logged ( x ) ->
console.log( @[x] + "" )
# random function that calls other function, our logging lets us trace the calls
# this one provides a name
bazz = logged "bazz", ( x ) ->
foo.call @, x
# test
bar = fizz: "buzz"
bazz.call bar, "fizz"
Note also how splats simplifies this operation. Destructuring and the existential operator makes the logic in the decorator function a little cleaner. String interpolation makes the logging easier.
Additionally the use of implicitness really makes it shine and fit together well, rather than being mere eye-candy. There's no wrapping in parens to decorate, making it harder to mess up, easier to modify, and easier to parse visually and perhaps programatically.
I think a lot of people are deceived when it comes to CoffeeScript, they see a lot of little things which seem nice...but individually they seem pointless or minor. They are deceived on two parts: a lot of these "little things" are actually quite powerful on their own, and additionally they mesh in a way that is greater than the sum of the parts.
All these little nice things can add a powerful boost to expressiveness and once you spend some time with them it really changes how you think and write code. That's another thing I would note is that CoffeeScript is for people who want more expressiveness/find these things more expressive. If you are looking for something else, or think in a way that has an impedance mismatch with the CoffeeScript philosophy, obviously you should look elsewhere.
(If anyone's curious, this decorator makes it so every time a decorated function is called, it logs the function's name if provided, the number of defined arguments it takes, and how many
it was actually passed.)
I would also note that scopes function the same in CS as they do in JS, the only difference is that in CS you cannot shadow variables from an enclosing scope, and there are no implicit globals.
In terms of OO, CS adds syntactic sugar for perhaps the most common inheritance pattern in JS.
I would argue both of those are good things, though I respect other people might think otherwise.
I dont see why he didn't use do "var game_piece , _i , len;"
He doesn't need multiple i's nor lengths. The JS example is just a very poor example of coding. (in fact he could of just simplified it further down by having one loop and a variable to the method, to be executed on those pieces.)
CoffeeScript is very nice, but I want to see examples of why to use it that will actually save me time. Compared to the examples, there are better ways to code and tons of easy ways to do OO with certain frameworks/toolkits.
Which keyword is useful? Var? CS will put it back at compile time, don't worry. And it will do it in more consistent manner than many coders will manually.
I have no problems with symbolless maps, and CS will save your ass from being bitten by IE because of stray comma.
I came here to post just this. While I like CS, JS isn't this horrid beast people keep making it out to be; often the solutions can be incredibly simple, it's just a matter of thinking about it.
It makes the article very misleading. Yes, CS looks great next to garbage output--but there are about a dozen ways to accomplish these tasks in JS and most are almost as concise as the CS examples.
Honestly, if that type of output is why people think Javascript is "hard" or "convoluted," then maybe CS is right for them. As with any tool, a proper knowledge of its use is required and anyone who would write code like that clearly doesn't really know their tool.
In the first example I would have written the original handler like this, for example. Written more concisely it doesn't present an immediate need for shortening or clarification by CS:
document.onkeydown = function(event) {
var key_to_func = {
37: "pan_left", 38: "pan_up",
39: "pan_right", 40: "pan_down",
189: "zoom_out", 187: "zoom_in"
};
for (var i in game_pieces)
game_pieces[i][key_to_func[event.keyCode]]();
return the_screen.refresh(game_pieces);
};
The class example is better but I haven't found much use for the JavaScript prototypes to build class-like constructs. Instead of using prototyping I generally just create objects and shove stuff into them. YMMV.
Last example is merely a transformation of the first version. The constructs used are quite similar: it would have been nice to see CoffeeScript transform the actual paradigms used in the code. The CoffeeScript version still reads like JavaScript, just with slight syntactic sugar.
Mere syntactic sugar might actually be the core idea of CoffeeScript (instead of landing a somewhat higher-level language on top of JS) in which case the example illustrates nicely why the gains from switching from JS to CS are mostly cosmetic. You can compress your code conceptually much better if you just write JS more functionally, i.e. write a few quick functions to provide map/filter/reduce and some helpers.
I absolutely don't get it. The CoffeeScript code looks way to obscure to me. I don't need more punctuation marks. List comprehensions can just be written in JavaScript very easily. jQuery provides them OOTB. Improved switch statements seems pointless when you can use a dispatch table. I'm all for better OO syntax, but I'd much prefer something slightly more verbose and transparent. This looks like an attempt to put Perl in the browser.
If there's a case for coffeescript over simply biting the bullet and learning to love JavaScript, this blog post doesn't touch it. If anything, well-written JavaScript code would be cleaner than his coffeescript examples (as noted in some commentsl although no doubt his coffeescript could be improved too).
I hate to harp on one minor point that he made, but I strongly disagree with his assertion that you could dump CoffeeScript, stick with the generated JS, and be happy with it. The generated JS he showed in those examples was terrible, and would be a maintenance nightmare.
CoffeeScript is interesting, but to be more so it shouldn't be limited to browser scripting. Until it doesn't become more general purpose i'll just stick to Python or Node.js
CoffeeScript and Node.js get along fantastically. When the "coffee-script" library is loaded, you can even "require('foo.coffee')" directly, making it easy to mix-and-match JavaScript and CoffeeScript files.
Sam Stephenson, the creator of Prototype.js, has been doing all kinds of awesome things with CoffeeScript and Node.js. And there's a chapter of my book on it...
Well but this isn't written in CoffeeScript. This is what I was saying: CoffeeScript can work alongside Node.js but can't access the filesystem. It might be good in its own right for DOM scripting and such but it doesn't open any more doors than Javascript.
OT question. How healthy is the Twisted ecosystem these days? Besides it being stable and been around for years, how does the post-divmod horizon looking? Is the whole stack still being maintained?
All of the old Divmod team are still hacking Twisted. It's still maintained, everything gets taken care of, and there's really no doubt about Twisted's future.
I fail to understand how this gets to be on the first page of HN, sided by links to the usual great stuff. My opinion worths for what it worth, but I would say this is a rather bad article and show some poor programming examples.
As many pointed out (five proper versions of the first snippet so far), the examples are not really valid.
I do not necessarily agree with the trend of criticizing javascript of being a language that needs to be fixed. Quite frankly, it is a proper language.
Coffescript introduces some practical sugar, class construct being IMHO the best plus as javascript class definitions are rather verbose. CS object notation is another neat advantage.
Many other things on coffeescript appear to be concepts that for some reason are fashionable these days such as the arrow or the conditions after the statement.
I write javascript everyday and I absolutely don't feel like there are anoyances which need to be taken care of urgently. It's a language as enjoyable as most. Cofffescript does look cool and I do plan to use, at least for fun if not for any other reason.
But saying that is the missing piece, or that is the long expected replacement for javascript, sounds like fanboyism.
> I fail to understand how this gets to be on the first page of HN
Same reason every shitty go article out there reaches HN's front page (or reached until pretty recently), same reason /r/prog's frontpage is cyclically full of a single technology or language: it's what most denizens of the place currently have a hard-on for.
Obviously I'm a fan of CoffeeScript; this is a minor bug and I expect it to be fixed. But let's be fair in making the case for it. Well-written JavaScript will always look better than CoffeeScript output; it just takes a lot more work.