12 ms·
CoffeeScript: less typing, bad readability
- TeeWEE 14y agoThe big point here: less characters for the same logic is not always better. Saying that you need less characters to write function x in coffeescript compared to javascript doesnt mean it is better. Its all about syntax and semantics. Code from languages with a small and consistent syntax, one-way-to-do-it, and a easy semantics are easier to understand than languages with a lot of semantics. For example, Scala is cool. But also overly complex. The same holds for C++. But languages like clojure are very simple to grasp and the semantics of these languages are very small.
- systems 14y agoon one of the slide in this presentation i found this interesting ( https://speakerdeck.com/u/clkao/p/livescript-tax-free-javascript https://speakerdeck.com/u/clkao/p/livescript-tax-free-javasc... ) Javascritp + ruby = coffeescript coffescript + perl = coco coco + haskell = livescript So i think coffeescript is not the end of the line, and i think this mean, there is a serious need for a better javascript
- rimantas 14y agoSeems like there are two types of developers: those who don't want even to hear about CoffeeScript and trying hard to find deficiencies in it and those who embraced it and feel unhappy every time they are forced to work with vanilla javascript again.
- jlongster 14y agoOr, there are different opinions on how things work, each finding their language superior in writability and readability. There are no absolutes. This is all subjective.
- evilduck 14y agoExtremists are generally the noisiest. I use CS in a Rails project along side JS without a problem. It's not a massive web site but I haven't hit any big snags mixing the two.
- proksoup 14y agoSounds pretty accurate to me. It's the "unreadable" problem that boggles my mind. "OMG it's change, run away!"
- debacle 14y agoI find this review very even-handed. It doesn't really make any bold claims, but it does provide a slew of evidence.
- cheald 14y agoEh. I think it's pretty silly. It basically boils down to "If you write terrible Coffeescript, it's hard to read". Duh? Any time you are writing code that is ambiguous, use what you need to in order to clarify it. Don't omit punctuation just because you can if it makes the code less readable. action(true, option1: 1 option2: 2 ) Using empty parameters in a function declaration is even funnier; you're adding punctuation that makes the code more vague. Just omit it! doSomething -> 'hello' doSomething(-> 'hello') The third example is totally valid, and one I completely agree with - omitting parentheses on inner nested function calls makes for unreadable code. Don't do it. The fourth example - complaining that inconsistent indentation produces inconsistent results - is just incomprehensible to me. When you're using a whitespace-delimited language, you'd best pay attention to your whitespace. Ambiguities with optional curly braces are certainly nothing new to Ruby developers. Convention is that only the last hash in an argument list may have its braces omitted (or more stringently, a hash may only have its braces omitted if it is the last parameter in the list). Makes for finely readable code. Don't write unreadable code. One of the fundamental rules you should follow when working in any language is "don't be clever". Optional parentheses can make for very clean code, but if you try to get "clever" with them, you end up with ambiguous code. List comprehensions are awesome but if you use them when there's a simpler construct you can use, you're doing it wrong. You can write bad, unreadable code in any language. Part of maturation as a developer is learning to write readable code, not just working code. A bad workman blames his tools.
- debacle 14y agoPeople make the same arguments about Perl, but CoffeeScript doesn't have CPAN. > Optional parentheses can make for very clean code, but if you try to get "clever" with them, you end up with ambiguous code. Seriously? Using extra parenthesis to add clarity is being clever? I always thought it was being safe.
- cristianpascu 14y agoI have recently implemented to quite large project with CoffeeScript, the most recent one for a full export to HTML for http://flairbuilder.com http://flairbuilder.com, and I have to say that CoffeeScript is a superb language. It's a pleasure to work with. The kind of problems that the article points out are easy to spot. If small syntax changes yield significant output code, that will be immediately reflect in the program execution. Plus, a decent code base will have unit testing in place, which should catch more intricate, harder to catch, unwanted code flavors.
- streptomycin 14y ago> The kind of problems that the article points out are easy to spot. If small syntax changes yield significant output code, that will be immediately reflect in the program execution. > Plus, a decent code base will have unit testing in place, which should catch more intricate, harder to catch, unwanted code flavors. That's rather optimistic.
- whelps 14y agoLook at it this way. Is it easier in general to read JavaScript on a large project over time or CoffeeScript? Sure, with either one there are things that could be annoying, just like with any language, but overall I would want to rely more on CoffeeScript than JavaScript. The reason being that for junior developers and other people that contribute to your codebase, CoffeeScript forces them to adhere to certain conventions that normal JavaScript does not have. Sure, if you have a great team that does everything perfect, well formed JavaScript can be easier to read and maintain, but that is not the normal case.
- jashkenas 14y agoMost of the bad code examples in this post are taken from the CoffeeScript compiler itself. For that I have to say "mea culpa". There's a lot of overly clever and dense bits that have accrued in the compiler over time -- sometimes due to the tangly nature of the codebase, but also sometimes because we tend to use the self-hosted compiler as a test bed for edge cases of combining different language features together. If you're looking for more regular style, this style guide is a better place to start: https://github.com/polarmobile/coffeescript-style-guide https://github.com/polarmobile/coffeescript-style-guide
- lowboy 14y agoPerhaps a style guide should be put up at coffeescript.org, or at least linked to.
- mcgwiz 14y agoPerhaps a style guide should just be encoded into the compiler.
- WickyNilliams 14y agoI was literally coming here to post this response. It seems like a revolution in (usage of) coffeescript is needed in much the same way Crockford's Good Parts paved the way for writing good javascript. Note: I'm not saying Crockford was singularly responsible for this, but The Good Parts was certainly well-received and very much popularised for it's opinionated views on the language. Edit: I mean in terms of coding style, CS itself has already cut out a lot of The Bad Parts of JS
- flywheel 14y agoHow much of your time is spent doing damage control?
- bicknellr 14y agoI feel like CoffeeScript is failing at what it's attempting to do if it needs its own style guide.
- jaysoo 14y agoI myself enjoy using CoffeeScript, but I understand it might not be for everyone. It's always good to look at the pro/cons before choosing a language, so I think discussions like this is good. That being said, some of the problems this article points out can be addressed by going back to more JS style. e.g. Not relying on implicit parentheses/commas/braces I like the "Fancy" for loop because it's closer to what I do in Python (yes I know they are not exactly the same). Same thing with the "Tricky" if statements. Also the redefinition shortcuts provided in CoffeeScript is pretty much what I do in plain JS anyway. e.g. JS: foo = foo || 'bar'; CS: foo or= 'bar'
- pistoriusp 14y agoCS 1.3.1: "Conditional assignment of previously undefined variables a or= b is now considered a syntax error."
- jaysoo 14y agoYeah I know. It was just a quick example. It's useful for something like: f = (options) -> options.foo or= 'bar' # ...
- latchkey 14y agoI agree, it is too bad that CS has so many optional ways of doing things. That said, it is possible to write unreadable code in pretty much any language. If you have a good style guide and stick to it, it is easy to avoid all of these issues.
- tete 14y agoI don't consider this article bad at all, because it really makes some good points. However a lot of criticism seems to come from the fact that the author is a Python programmer and therefor wants CoffeeScript to be more like Python. No, I am not saying something like the author not understanding it isn't meant to be Python, but for example the implicit vs explicit debate is certainly a more philosophical view. Ask people who prefer other programming languages and they will have a different view. Hey, after all that's why there are so many, even if Ruby, Perl, Python, Falcon, etc. have very similar use cases. My opinion for example is that dynamic languages are very implicit in first place so saying you don't want that (at all) doesn't make too much sense. I also don't have problems reading CoffeeScript, but occasionally had problems with very explicit languages being too verbose which can make it harder to follow. So looks like my mind works slightly different here. But back to the article. There are lots of valid points. I think coding guidelines, which one should have working in a team, no matter what language could solve some of them. Some points look a bit like mixing different styles on purpose and at least can't see how you could find something like that in the wild. Just because you can code ugly, it doesn't mean you have to, but again that is more of an opinion. Some people like usually verbose languages, because they say they are easier to read, others like ones with shortcuts or where you have multiple options to express things, making it easier to read (for some people). I for example always enjoyed the fact that Perl has unless and until in place of negated if/while. But that's more what you prefer. But hey, CoffeeScript is all Javascript, so if your team doesn't like it it's (comparatively) easy to step by step switch back.
- alecperkins 14y agoIt's funny, because as a big fan of Python who has had to do a lot of CoffeeScript lately, I find CoffeeScript very similar to Python, and very readable. It's certainly more readable than JavaScript, when you don't get fancy. It's called "Unfancy JavaScript" for a reason. Many of the issues raised in this article can be solved by "simply" not doing it (admittedly not always a real solution). Just because the language allows something to be done, doesn't mean it should be done that way. Our team has a styleguide that clearly explains good and bad practice, for CoffeeScript AND Python. (It's possible to do bonkers stuff in Python, too, just harder.) It includes things like: use explicit returns, especially when intending to return nothing; include parenthesis unless it's more clear without them (callback as arguments). Yes, it'd be great if the language were more explicit and made it harder to do confusing thing. But, its core goal is being "just javascript", which prevents some of that explicitness. Also, the flexibility lets the real goal be clarity. I find my_object = key: 'value' fn: (response) -> console.log(response) to be more clear than my_object = { key: 'value', fn: function() { console.log(response) } } because it doesn't have all the crap. CoffeeScript's whitespace syntax is even more helpful when those objects start getting nested. Plus, not having to deal with trailing commas is amazing. At the same time, someFn arg1, arg2, -> doStuffInACallback() , arg3 can be confusing, so parens help: someFn(arg1, arg2, -> doStuffInACallback() , arg3) I try to not be "that guy" when it comes to CoffeeScript, but it's easily one of my favorite languages now. All the crap that JavaScript requires is just gone.
- deanotron 14y agoI've been using coffeescript for about two years - I thought it was the best way to keep the pleasant aesthetic of python, which was my favorite language, and have been happy working with it ever since. I just want to throw out a positive experience with it and to say that I don't support the author's premise of "here's some misleading things you can do with CS, therefore CS is unreadable". This applies to all languages, and 'fanciful' features and syntax should be avoided almost always in every language for the sake of readability. There are MANY reasons not to use coffeescript, but JS is all functions all the time, and -> is my best friend.
- viseztrance 14y agoI haven't used CS as much as yourself, but I don't find anything pretty in "element = =>".
- alecperkins 14y agoIf you use anonymous functions a lot, it's amazing: result = _.map object, (val, key) -> foo(val) is much cleaner than var result = _.map(object, function(val, key) { return foo(val) }); I think.
- deanotron 14y agoThat is a good example, and something that is eased by syntax highlighting (although I rarely implement double-bar function literals, keeping a pythonic 'self = this' reference is preferrable in most cases) Although it is all subjective aesthetics, CS shines when paired with underscore.js, and really all "callback-as-last-argument" paradigms, ie: _.each items, (item) -> # do stuff with item # ... (edited formatting, also what alec said below :)
- kin 14y agowhile the points in the article make sense and I agree, if you keep your Coffeescript code consistent I really don't suffer a readability problem, especially relative to JS where there's like 5x more code to go through
- kzahel 14y agoThat's an unfair hyperbole. CS saves you at most ~30% characters, and that's when omitting every parenthesis possible. I personally don't get excited by that prospect. Generators would get me excited, though!
- kin 14y agowell, personally when i converted over i never had to stare at these blocks anymore: } } } }); made code a lot easier to debug. and yes, consistency wasn't the only thing. i would say that converting over has a learning curve sure reading other people's code. but sacrificing readability long term compared to vanilla js? i wouldn't say that. i'm not saying there isn't ambiguity in the beginning but eventually you learn how to not do things in ambiguous ways.
- njharman 14y ago> you keep your Coffeescript code consistent That is not enough, because unfortunately, there are more programmers in the world than "you", and I have to use their code and / or work with them. When language has X options their is X! opinions on "consistent".
- deleted 14y ago[deleted]
- viseztrance 14y agoThe moment you try to do simple things like concatenating a string you realise that javascript is a bit more tedious than it needs to be. While nowadays I prefer coffeescript to js, I would rather have some syntactic sugar like scss is for css. I've looked into it but nothing has enough momentum to make me sure it will still be around in two years or so. As a sidenote, while I mentioned I prefer CS, have you ever tried using a ternary operator? or pass a callback function in jquery (ex. the hover out event)? or just return "this". There are so many things that feel so wrong.
- svachalek 14y agoFeel so wrong in... CoffeeScript? Or JavaScript? I think ternaries and callbacks are both much cleaner in CS (with the exception of "callback, something-else" which does end up a little funky unless you add parens). Just naming a variable to return it seems a little wrong to me but you can always leave the "return" in. "Optional" is very different than "never use".
- viseztrance 14y agoThose last things feel wrong in coffeescript. Honestly, what's more readable: x = a ? b : c or x = if a then b else c And for the last one: function() { // doing something return this; } -> # doing something @ Don't get me wrong, I love the fact that I can do nice stuff such as callback?() and some other nifty tricks, but while I'm still having fun using coffeescript, in my experience it's not that great as most people make it up to be.
- jashkenas 14y agoJust FYI, using standalone `@` isn't considered to be good CoffeeScript style. It's discouraged for this very reason -- just use `this` instead. The reason why it works in the first place is for consistency ... in every other context, you can use an `@` to replace a `this` or `this.`.
- 14y ago
- cnp 14y agoPersonally, i write my CoffeeScript with as much syntax as possible, to keep it as readable as possible: as a rule, I always use parenthesis and commas while leveraging CoffeeScript's "good parts". But that said, the last couple of projects I've written in pure JavaScript and it's actually made things much easier to go back and read. Like the author of this post, I too have had difficulty reading back over my old code and, at a glance, understanding precisely what's going on. Over the past couple of months I've gone from being absolutely devoted to CoffeeScript to on the fence, mostly due to readability. (I'd love to see a fork of CoffeeScript that forces syntax.)
- sixbrx 14y agoI haven't programmed in Coffeescript, but does it bother anyone else that new variables are introduced without "var"? When reading js, seeing the "var" really helps me to know the programmer's intent that this is a new variable being introduced, not an attempt to reassign one that should already exist. Does CS have features that make this point mute?
- masklinn 14y ago> I haven't programmed in Coffeescript, but does it bother anyone else that new variables are introduced without "var"? Yes. I've come to see it as a mistake in Python and Ruby both, and I'm definitely not pleased by its usage in CS. Even less so as it uses the same rules as Ruby's lambdas without the stops of its methods and global scopes.
- jeremyjh 14y agoI think it depends on what you are used to. I find "var" to be noise.
- svachalek 14y agoActually I think this is a big plus, as it's much more common to want to declare a new variable than to want to reassign a global, and hard to notice when something is missing like "var". It would be nice if there was an explicitly different operator for reassignment. (p.s. I think you mean "moot")
- jashkenas 14y agoFor more discussion of this feature -- see yesterday's conversation on Reddit: http://www.reddit.com/r/programming/comments/zx137/coffeescript_devs_dont_understand_lexical_scope/c68ydc7 http://www.reddit.com/r/programming/comments/zx137/coffeescr...
- mcmire 14y agoThis doesn't bother me at all. Mostly because this feature comes from Ruby and so I'm already used to it, but also because it takes away the nasty surprise that JavaScript gives you if you leave 'var' out. I find this invaluable. As for knowing whether or not a new variable is being declared, well, that's why you keep your functions (and therefore your scopes) short.
- andrewingram 14y agoA few years ago I made an email campaign editor using JavaScript, I re-implemented it in CoffeeScript a few months ago. What I now want to do is re-implement it in the good JavaScript I've learned from reading the code that CoffeeScript generates. There are some annoying parts of CoffeeScript. If your function takes callbacks as the first parameters, and another value as the second (such as setTimeout), you end up with some really awkward syntax. I've seen a lot of people define a delay method that swaps the parameters of setTimeout just so it's easier to use with CoffeeScript. Like the author of the article, I have a Python background, but I've also written a lot of JavaScript, I love the syntactic sugar that CoffeeScript brings, but I hate reading CoffeeScript code. The project that my re-implemented email editor is used in has a hybrid of JavaScript and CoffeeScript code, and I'm not kidding when I say that everyone (myself included) groans when they have to work on the CoffeeScript parts.
- ebiester 14y agoTo me, this says that you should define your callback as a function, and pass the function. If you're used to how to write functional code, this can be a clean way to do things. That said, I've seen the same problem myself.
- tiglionabbit 14y agoMaking the callback the last parameter is very common in JavaScript too. It just makes things look nicer when you want to put anonymous functions in there. Underscore.js does this for all their functions.
- jashkenas 14y ago> If your function takes callbacks as the first parameters, > and another value as the second (such as setTimeout), > you end up with some really awkward syntax. Hopefully no more awkward than the equivalent call in JavaScript. setTimeout (-> alert "later"), 300 Versus: setTimeout(function(){ alert("later"); }, 300); Or, on multiple lines: setTimeout(-> alert "later" , 300) setTimeout(function(){ alert("later"); }, 300);
- 14y ago
- tylerlh 14y agoYeah, well that's just, like, your opinion, man. -- The Dude. Personally, CoffeeScript has been my favorite thing to come about in the past few years.
- gothy 14y agoUsing CS for about 1.5 years now. Yes, there're ways to hurt yourself with bad CS code. This is also true for Python. When developer writes some fancy one-liner in CS or Python and I'm reviewing his commit, I just ask him to come over and explain what this thing is doing. Sometimes it takes more than 20 second to read and explain even by author. Then I say: "You wrote this line an hour ago and it's already hard for you to understand what it does. Imagine you'll need to change it in a month. You'll hate yourself. Go and rewrite this code explicitly to help yourself in the future." If you force yourself and teammates to write explicit code, you get all the pluses of CoffeeScript avoiding bad readability.
- iamwil 14y agoSome of the complaints in the OP aren't mistakes that I make often, so I guess I don't see them. Perhaps for someone that makes those types of mistakes often, it'd be a detriment, but so far, I've been happy with my coffeescript experience.
- dustingetz 14y agowow readability is about API design like requests vs urllib2: https://gist.github.com/973705 https://gist.github.com/973705 except when APIs get 100x bigger, API design becomes 100x more important. and using a language ecosystem that encourages good API design, over a language that is cobbled together and has no particular opinions about what good API design looks like[1] (or, even, bad opinions[2]), so that less experienced developers end up with decent output, is that much more important than concerns like parens, commas and braces. curly braces never made a project fail. shitty API design does. [1] javascript! [2] java! sheesh. there are bad things about coffeescript, but this stuff hardly matters.
- smacktoward 14y agoI don't have a strong opinion on the article itself (it seems well-reasoned to me, but I don't use CoffeeScript personally so who knows)... but the comments attached to it are hilarious. I think CoffeeScript has great readability, because I’ve taken the time to learn how it works. If you have to take the time to learn how to read something, it's not easily readable. CoffeeScript is only hard to read if you try to read it with a JavaScript mindset. Yes, why would anyone approach a tool pitched explicitly at JavaScript developers, whose "golden rule" is "it's just JavaScript" (see the top of http://coffeescript.org/ http://coffeescript.org/), with a "JavaScript mindset"? Truly, it is a mystery.
- masklinn 14y ago> If you have to take the time to learn how to read something, it's not easily readable. I don't think that's completely true. If you're used to algol or C-style, Lisps tend to be hard to read. Concatenative languages even more so. Not necessarily because they're hard to read in and of themselves, but because the "shape" of the code is "all wrong" compared what you're used to, and your usual anchors (keywords, binary operators, infix assingment, ...) are nowhere to be found. I mean Arabic or Korean are not necessarily harder to read than English, but you've got to know them and how they work before you even recognize patterns in the squiggly lines and little squares.
- Daishiman 14y agoNot really; Lisp is hard to read because the syntax is unusual, but it's not hard to understand because it's complicated. On the contrary, it has the most consistent syntax of any language. They author's point is that Coffeescript is hard to read because it has too many edge cases which are not easily understood under a smalla and consistent set of rules. I have not programmed with CS, but it sounds like a convincing argument.
- wonderzombie 14y agoOr, to restate this and amplify it a bit, Lisp syntax is hard to read because most people are unfamiliar with it. This isn't -- or should not be -- a problem if you need to learn to read a language in order to use it. (This is orthogonal to whether you want to learn it in the first place, or whether you "ought" to.) It is a problem if learning how to read and write the language isn't enough. The point TFA raises is that people who're familiar with CoffeeScript syntax may still make mistakes resulting in completely erroneous but valid code. Yikes. And the inherent nature of whitespace or indentation makes the problem harder to detect by cursory inspection. I have no strong opinions about CoffeeScript, myself. I just thought this was an interesting distinction, and a rare case where syntax makes a significant difference.
- mcantor 14y agoBoth statements do completely different different things, although they look very similar. This is true for both CoffeeScript examples he gave and their resulting JavaScript.
- armored_mammal 14y agoI concur with the author. When I write CoffeeScript I often use a more explicit or more c-like style for things I find ridiculously ambiguous or hard to parse when reading quickly. Particularly, if one line has lots of commas, I put parens all over the place because no matter what I do, having to manually parse the comma arrangements and figure out what's nested and what's a function does not go quickly. I also find myself writing explicit returns somewhat frequently just so it's much more clear what's being returned. The overarching issue is that the syntax blurs rather than pops -- there are too many instances where things that are significantly different in function look nearly the same.
- rayiner 14y agoI'm meh on significant indentation, but significant space characters is just a terrible idea. I blame Haskell.
- crazygringo 14y agoThis is a fantastic post -- I feel like I've run into all these crazy "gotchas" over the past year, and more. And the worst part of it is, nearly all the confusing/ambiguous/different compilation examples given rely on the undocumented rules CoffeeScript uses for parsing. It's amazing that, still, CoffeeScript's entire documentation is basically a "getting started" guide, and there is simply no reference documentation.
- TazeTSchnitzel 14y agoI personally describe CoffeeScript as "stabby". CS has all these little shortcuts and shorthands which seem great and appear to save time, but many of them are ambiguous, and then you get stabbed by their ambiguity, and you waste time debugging. Python, on the other hand, is still quite concise, but is generally very unambiguous.
- paul-woolcock 14y agoI always thought CS was a "kinda-python-y" version of Javascript, though I never actually used it. It surprised me, therefore, to see that the OP considers these two items to be principles applied to the design of the language: - Implicit is better than explicit - There is more than one way to do it These are the exact _opposite_ of a couple of the principles of the design of Python[1]. 1: http://www.python.org/dev/peps/pep-0020/ http://www.python.org/dev/peps/pep-0020/
- DasIch 14y agoIndeed but they obviously seem to apply to CS as he has shown in his examples.
- paul-woolcock 14y agoOh, I agree, it was just surprising to me to see them there.
- luriel 14y ago
- crazygringo 14y agoQuestion: am I the only one who's driven nuts by "if"s that come after the "then" part? E.g.: do_something(with, these, args) if im_supposed_to I mean, the processor/interpreter always needs to evaluate the "if" first, so what purpose does it ever serve to put it after the "then"? To me, it just confuses things because it feels like code is getting executed backwards -- like crossing an intersection, and then checking to see if the light is green. I know it works "in English" ("do this if that"), but when I scan other people's code I'll sometimes completely miss the "if" (sometimes it's just off the screen). Are there any examples where this reverse-if actually helps, instead of harming, code intelligibility?
- evanmoran 14y agoI find they are useful for shortcutting out of functions: throw 'error' if badness return null unless goodness Since it doesn't make sense to return or throw unconditionally it is makes it pretty clear that you should look for the if/unless.
- nemetroid 14y agoThough, what's the benefit of putting the conditional after? I find these: if badness throw 'error' unless goodness return null to be more readable
- shardling 14y agoIt's definitely nice to see the return at the beginning of the line -- makes the code easier to scan. And anytime there's code after a return, it had better be connected to a conditional. :)
- nemetroid 14y agoThose are good points. I'd probably make it multi-line: if badness throw 'error' unless goodness return null
- 14y ago
- mratzloff 14y agoComing from Python [...] For example, in C-like languages, you can omit curly brackets after a conditional expression if you only have one statement: if (condition) action(); But what happens if we add a new statement: if (condition) action(); action2(); Of course, that doesn't seem to be an issue in Python, the language he's coming from. Most of his points are similarly contrived and could be equally applied to Ruby, a language which doesn't require parentheses and quite a lot of developers seem to like, or Python which is similarly whitespace-dependent and quite a lot of developers also seem to like. But inflammatory headlines do drive traffic from HN... Given that CoffeeScript doesn’t fix any of the fundamental problems of JavaScript I think most developers who are well-versed with both JavaScript and CoffeeScript would disagree that CoffeeScript doesn't fix any of the problems with JavaScript. It certainly makes it easier to loop through object properties. It makes code more readable in a number of ways; post conditions, list comprehension-like syntax, simpler loops, the existential operator (`foo?`), and the maybe object-like syntax (`foo.bar?.baz?.quux`) are definitely improvements. You can of course write bad code in any language, no matter how structured it is. I myself am about to embark on refactoring a massive, terribly-constructed Python system that processes millions of requests each day. The author didn't follow the strictures of the Python community at all. How is that any different from someone who exercises poor judgment when writing CoffeeScript? It's not.
- Macha 14y agoThe issue with the optional curly brackets is that for new users, or even experienced users reading through code quickly is that at first glance: if(something) doSomething(); And: if(something) doOneThing(); doAnotherThing(); Both look like they should execute the same way - running the indented code if the condition is true. The reason this is a problem in C and not in python is that in python, this code operates as it intuitively looks, while in C, it does not. (It can trip up experienced users if they're not paying enough attention and their mind just assumes the curly brackets are there.)
- artsrc 14y agoThe issue is that: * Humans use indentation * The Compiler ignores indentation * The indentation and the the compilers interpretation are different
- ilaksh 14y agoJust because you CAN do something in CoffeeScript doesn't mean you SHOULD, or should ALL of the time. Just like in JavaScript where, if you want, you can write all of your code on one line, but you shouldn't. action true option1: 1 option2: 2 If you really use CoffeeScript regularly, that isn't confusing. I don't usually write it that way though. I would do this: options = a: 1 b: 2 action true, options doSomething () -> 'hello' just isn't valid code. Usually I would write doSomething -> return 'hello' or maybe doSomething -> 'hello' If you write it the way he did, the parenthesis are confusing. For this one: action = (token, i) -> @tokens.splice i, 0, @generate 'CALL_END', ')', token[2] -- first of all, you always want to indent two spaces. But the main problem with that is in CoffeeScript you do need to use parenthesis after the first call because your code will be unreadable otherwise. You just can't write it the way he did. moveTo 10, 20 10 doSomething 1, 2 3 4 doSomething 1, 2 3 4 Those are ridiculous examples. No one does that. You just write moveTo 10, 20, 10 doSomething (-> 'hello'), 1 Indentation is significant in CoffeeScript, just like it is in Python. Just having a parenthesis shouldn't change that. Anyway, what I do is this: somethingDo = (ms, func) -> doSomething func, ms and then I can just write somethingDo 1, -> 'hello' action(key: value, option: value, otherValue) You don't write it like that if the function takes two objects. You would probably just write action {key: value}, {option: value}, otherValue x = { key1 key2 key3: value3 } This is called destructuring assignment, and its part of the new ECMAScript. Its useful to not have to repeat key1, key2 everywhere when the variable with the value has the same name as the object property. The extra curly braces are just necessary to differentiate from the normal syntax. Sometimes yes/no or on/off are more readable than true/false. That's an advantage. x = 1 if y != 0; Don't use semicolons in CoffeeScript. I also don't put if statements at the end of a line because I don't believe that is very readable for most people including me. Also, in CoffeeScript its probably better to use isnt instead of !=, although rather than !=, you would want !==. if y isnt 0 x = 1 I'm not that sure about the use of unless, although it probably is a little bit more readable overall. break for [tag], i in @tokens when tag isnt 'TERMINATOR' @tokens.splice 0, i if i He says that is supposed to delete TERMINATOR from tokens. I tested it, it doesn't do anything, and the second example of the correct way doesn't work either. I think he meant this: filtered = [] for token, i in tokens if not (i is 0 and token is 'TERMINATOR') filtered.push token i += block.call this, token, i, tokens while token = tokens[i] Another example of something you CAN do in CoffeeScript but shouldn't. Actually it is a bad idea in general. I think a CoffeeScript programmer would actually write something like this: class Parser block: (token) => @currentNode.push new Token(token) parse: => for token in tokens @block token I would never write something like 'mainModule.moduleCache and= {}' Instead of js = (parser.parse lexer.tokenize code).compile options I would write tokens = lexer.tokenize code parsed = parser.parse tokens js = parsed.compile options
- eranation 14y agoI guess I'm lonely in this world, but I really want a statically typed JavaScript alternative. Dart is nice, but no JS interop (yet), GWT is just Java, which is not the most fun thing in the world, ClojureScript is nice, but not static typed and Lisp is a bit too extreme for me, but the new Scala JS DSL seems worth waiting for.
- ebiester 14y agohttp://haxe.org/ http://haxe.org/ I would say ActionScript, but FalconJS hasn't been released yet. There are other projects (such as roy) that are more functional in nature as well.
- eranation 14y agoI have to try Haxe, but I can't help but wonder, it's been around for a while, how come it didn't get more traction? I assume I'll have to try and find out. I was a flash developer way back (2003), I hear you.
- spacemanaki 14y agoYou're definitely not alone: http://www.haskell.org/haskellwiki/The_JavaScript_Problem http://www.haskell.org/haskellwiki/The_JavaScript_Problem http://roy.brianmckenna.org/ http://roy.brianmckenna.org/
- eranation 14y agoYes! I actually ended up in both places yesterday before seeing this comment, never thought I'd seriously consider Haskell, but now I start to understand why so many people like it.
- epidemian 14y agoNope, you're definitely not alone on that. I've been thinking about experimenting with doing a simple staticly typed language that transcompiles to a readable JS. Roy [1] is really nice for example, but i think the generated JS is quite bloated, mainly because it maintains the lazy semantics of Haskell. [1]: http://roy.brianmckenna.org/ http://roy.brianmckenna.org/
- d0m 14y agoThanks for this post. This is actually how I feel about CS but could never actually explain it correctly. I find it very hard to read other people code because of all these implicit rules that are more often than not ambiguous. Yes, sometime it's shorter but not necessarily faster or easier to read.
- gbin 14y agoI had this same feeling programming in ruby few years ago when no formal language grammar was defined (with really weird problems with : vs [space]: AFAIR). Is it the same for CS ?
- paulbjensen 14y agoI wrote Dashku entirely in CoffeeScript. It was a productivity boost, and for that I owe it my firstborn child.
- ryankshaw 14y agowhenever I see something like this that tries to rag on coffeescript it seems like they all reference ryan florence's post from a while ago: http://ryanflorence.com/2011/case-against-coffeescript/ http://ryanflorence.com/2011/case-against-coffeescript/ for the sake of clarification, ryan is sitting right next to me, writing coffeescript (as with all new code we write here at instructure, see: https://github.com/instructure/canvas-lms/tree/stable/app/coffeescripts https://github.com/instructure/canvas-lms/tree/stable/app/co... )--and loving it. whatever "crazy gotchas" he found back then are obviously trivial to how much easier coffeescript makes life. it seems like every third tweet he makes is about how much he loves CS now: https://twitter.com/ryanflorence https://twitter.com/ryanflorence Other than that, everything in this post just comes down to "just because you can doesn't mean you have to or should." disambiguate if helps make things readable
- jashkenas 14y agoPerhaps it's time for Ryan to write that follow-up post ;)
- johnx123-up 14y agoOne person has opposed CS and now using it. Many people (including me) tried CS and back to JavaScript. It's all about readability, team size, and choices.
- tharris0101 14y agoThis is exactly why I stopped using CoffeeScript. I hate Javascript so I was excited when I saw CS for the first time but after a while I realized I was doing two calculations in my head: 1: What is the JS that CS was generating? 2: What is the JS doing? Maybe I just didn't give it enough time, but it seemed quicker and more reliable for me to just suffer through the JS syntax.
- ricardobeat 14y agoThough most examples are not something you'd write normally, this line is what kind of flopped the article for me: Given that CoffeeScript doesn’t fix any of the fundamental problems of JavaScript same for a comment here: coffeescript doesn't bring much to table There is so much coffeescript adds that I find these laughable: string interpolation multi-line strings comprehensions guarded loops (hasOwn...) easy constructor/prototype definition (class) avoiding global leaks/shadowing function binding splats, defaults safe usage of reserved names existential operator chained comparisons READABLE regular expressions This just off the top of my head. These make a huge difference to writing code everyday. I've been writing CoffeeScript for 90% of my projects in the past 2.5 years and it pretty clearly affected my productivity for the better. I can only conclude that whoever says "coffeescript doesn't add anything" hasn't really used it for work. Case in point, if you look at the linked article at the end you'll see an update by the author: I actually love CoffeeScript now that I've been writing it for a year.
- sktrdie 14y agoI totally agree that CoffeeScript brings a lot to the table compared to old feature-less JavaScript. But the author is talking about readability of the language, and not about the features that it has. The problem that he points out about "Implicit is better than explicit" and "There is more than one way to do it" are quite serious problems that modern languages shouldn't have.
- ricardobeat 14y agoSee quote at the top, last paragraph from the post. His conclusion is that these readability problems swamp everything that coffeescript has to offer, which I think is really not the case - especially considering these are mostly style issues.
- tiglionabbit 14y agoOh dude, just learned something new from this article. options = { a b c } generates options = { a:a, b:b, c:c, } I have a lot of maps in my app that look just like that. It'll save me a lot of repetition.
- j-kidd 14y agoMay I ask what are the use cases for maps like that? I don't think I have ever needed one myself.
- lowboy 14y agoI have situations like this quite frequently where I need to turn vars into members of an object: title = getTheTitle() img = (shouldWeGetImg) ? getImg() : "placeholder.jpg" body = ... # 8 lines of code to define body, some that reference title and img # this: obj = { title, img, body } # instead of: obj = {title: title, body: body, img: img}
- tiglionabbit 14y agoPretend there are newlines after a, b, and c. HTML ate my whitespace :P.
- jtms 14y agoCoffeeScript readability > Javascript readability and that's all that matters to me
- lmm 14y agoBut the whole point of the article was that that isn't true, because CoffeeScript makes more things optional (e.g. in Javascript if you don't see brackets then you know it's not a function)
- jtms 14y agoYeah that's obvious, but I disagree with "the whole point of the article" hence my previous statement.
- lucian303 14y ago"readability is more important than writability for a programming language" Couldn't agree with you more. Readability is measurable and considering that a lot of programmers come from C-type languages, I really don't see why people try to modify an existing formula (as badly implemented as that formula is in JS). tl;dr: Let's face it, if you're using Coffeescript or similar because there are too many braces or parenthesis, perhaps you should quit development right now and take a class on basic algebra, quit that and save the world your horrific code. Seriously.
- klibertp 14y agoReadability is measurable, that's true, but the second part of your sentence makes me wonder if you really understand what readability is. Do not confuse readability with familiarity. Also, don't forget that readability is a function of both syntax and semantics. Also, I really don't know what connection there could be between aesthetic preference and quality of code produced. Are you aware of some study that show that kind of connection? With conclusion which says that if I like line noise then I am a great programmer, and if I like whitespace I am bad? If not then your 'tl;dr' is just stupid, sorry.
- lucian303 14y agoThis isn't about aesthetics, it's about grammar. Just as in written human languages, computer languages have grammar that make things easier to read and understand. How well that grammar is done depends on the language. My point is that if aesthetics is one of the reasons you choose a language, you really don't understand software development or the simple idea of "use the right tool for the right job."
- orangecat 14y agoMy point is that if aesthetics is one of the reasons you choose a language, you really don't understand software development Some would disagree: http://paulgraham.com/pypar.html http://paulgraham.com/pypar.html
- ojosilva 14y agoAfter reading this, I felt the urge to classify key aspects of write and readability of the programming languages I've dealt with over the years. How easy or fast it is... - to write what I want to achieve - to write something that makes me feel creative - to write something that makes me feel tidy, organized - to write a syntax error - to write a logical error - to step into a "gotcha" - to find that bug - to grasp a short snipped - to grasp a 20K loc app - to read my own code 1 week later - to read my own code 3 years later - to read somebody else's code Now trying to rate languages by these parameters is a tough job that I can't even imagine how to tackle. In many instances it doesn't even has to do with the language itself, but rather with my experience and relationship with it. But any exercise in this direction gives some food for thought while trying to find the right tool for the next job. Or something to think about when looking back at some of the choices I've made through my programming lifetime.
- orangecat 14y ago- to grasp a 20K loc app Although, 20k lines of Python is probably doing much more than 20k lines of Java.
- tjholowaychuk 14y agoGreat article, totally nails it. No "good" language design should be so ambiguous
- beernutz 14y agoBadly written code is badly written code in ANY language.
- losvedir 14y agoParenthesEs is the plural, parenthesIs is the singular. Normally I don't do the spelling/grammar thing, but it was consistently wrong in the article, and at least a half dozen comments here were getting it wrong, too, so I figured a public service announcement was in order.
- endemic 14y agoHere's my own anecdotal example of CoffeeScript's readability. Once, before banging out a bit of complex code, I thought I'd write out some psuedocode to help wrap my mind around what I wanted to do. I type out my psuedocode algorithm, realize I've written valid CoffeeScript, then uncomment it. That's the experience that made me think CoffeeScript is MORE readable than JavaScript.