Hacker News new | comments | show | ask | jobs | submit login
CoffeeScript's Time is Waning For Me (mattgreer.org)
27 points by bpierre 1232 days ago | hide | past | web | 62 comments | favorite

"As my project grows in size, significant whitespace becomes more and more of a problem. It’s just plain not readable or visually parsable. Your files become a wall of dense text. Damn you Python, damn you to hell!"

I would appreciate an explanation of this paragraph. How exactly does project size compound issues with significant whitespace? Are you indenting five levels or something?

I'm curious about this statement as well. It sounds like the author might be:

- Creating big complex methods instead of breaking code into smaller (testable) ones?

- Nesting callbacks multiple levels deep, instead of using something like Node Async to flatten out code flow?

- Choosing a Coffeescript code style that leads him to put callbacks on their own line, or something like that?

- Something else?

Not implying the author is wrong by any means - there are probably some scenarios where coffeescript isn't the best whitespace-wise. The thing is, readability is one of the huge reasons I use coffeescript, and I feel like it's largely compatible with the whitespace patterns I used in javascript. Even for large NodeJS or Angular projects, I've found that it is consistently easier to read and edit than Javascript.

I'm the author of the blog post. Significant whitespace is pretty dividing, and really boils down to preference. I have a strong dislike for it, and have avoided any language with it, CoffeeScript being the only exception.

Here is a typical snippet of my code as seen in my editor: http://i.imgur.com/2yVhgcz.png

IMO, those four methods really bleed together and are hard to discern, not to mention the if statements. I also think for the most part I stick with code that's "whitespace friendly", getAll there is a really long method by my standards.

Yeah, I could put more blank lines between the methods and probably some other things. But I also think a closing brace or an 'end' makes a world of difference. Really helps break up the space and compartmentalize it.

Not everyone thinks this of course. For many code like this is just fine. Like I said, it's all preference.

Try removing the indentation guides or decreasing their contrast so that they are just barely visible. They appear to cause strong visual grouping between code blocks and make it harder to see what's what.

That's a fair point. I will try that and maybe some more tweaks too.

Seems like you really have a lot of contrast in that theme. Also I hope you will consider dropping the extra parentheses.

And instead of dropping CoffeeScript I hope you will try out ToffeeScript. But just use the basic ! thing, you don't need the other stuff like auto callback.

    e, data1 = fs.readFile! 'foo'
    e, data2 = redisclient.get! "thekey"
    console.log data1
    console.log data2

When I first started using CoffeeScript I dropped just about every optional character you could. Lately I've been going in the opposite direction and adding most of them back in. I find this is also a matter of taste and experience. Whether I add the parens or not depends a lot on what's going on at that point. I do appreciate how flexible CS can be here.

I'm interested in things like ToffeeScript and JS generators. I do like what they do for code readability.

I'll go ahead and back this point up also. The visual white space is actually making it harder to read the code.

I think that's not a problem with significant whitespace, but the problem with CoffeeScript syntax. I'm programming in Python and had been programming in Coffescript and I always found Coffescript code much harder to read than code in Python. I don't know exactly what causes this, but my guess is that indented blocks of code in CoffeScript can appear after any line, so you don't have visual anchors that will indicate where one block begins and other ends. In Python however, indentation is always comes after keywords like def, if, class, for etc... and those are always highlighted by your editor so your eyes can always catch the block start very quickly.

Does that suggest you don't indent your code at all? Do you miss out on the cheapest visual cue to understanding your code? If you indent code already (with all the curly braces) then significant whitespace means your normal indentation sans 2 curly braces every time.

I totally agree with you about the spacing between methods. I've actually found myself putting a double-space between methods, but I do that in most languages so it hasn't bugged me as much. Thanks for posting the image!

I did find that odd. Whitespace helps you get away from "a wall of dense text." I'm not clear on how mandatory whitespace could exacerbate the "wall of dense text" problem.

Does the author want to skip the indentation some of the time? I can think of a few marginal cases where that would be preferable. But in the vast majority of cases, you should indent any nested structure that has its own line(s). Indentation is essential for readability.

Anyone who has maintained Makefiles will have a strong opinion on semantic whitespace.

Maybe not opinion, but reaction. Generally involving visceral fear or anger.

It's not that it's always bad, every hour of every day. It's that one time, at 1am, when you shouldn't be working but you are, something doesn't behave properly, and it turns out Bob the Intern re-indented a block of code to use tabs instead of spaces[1], but you couldn't see it because your editor is configured to use four spaces per tab and your coding standards dictate four spaces per level of scope.

[1] Why are you using spaces anyway, you complete and utter savage?

Which is why you set your editor to use something other than the same number of spaces as your indent levels. It works especially well if one isn't a multiple of the other - e.g. having the editor display tabs as 5-space width.

Anyone who has maintained Makefiles will also have a strong opinion on compiled languages.

I'd really like further explanation, too. If you're not properly indenting code in large projects — whatever the programming language is — I'd really hate working with you.

just want to drop another vote against against significant whitespace...

i find it slows down my coding because rather than coding & then quickly tidying i instead have to obsess over this tidying at every step or the code won't work in the first place. I find it more efficient to do the code grouping as a "post-POC" task (or when things are starting to look confusing) and to leave the visual look to my discretion. I feel like whitespace languages are kindof subliminally forcing you toward 1 code style. There are some complex functions that look better to me certain ways -- specifically in cases where a group of commands are essentially executing one simple function. Once they work they can be forgotten & the programmer can de-emphasize them in some way according to taste

anyway, I am not a CoffeeScript guy. I've been avoiding it and waiting for Dart or something like that to take hold, since I'd like to see some serious language benefits if I'm going to have to introduce a compilation step. It's one of those things I remain slightly bitter about because some shops judge you for not being into it (as well as Sass, Haml) even though they offer negligible benefits for many projects. That said, I can imagine cases where CoffeeScript would offer significant benefits (they are right there in the tutorials) but I haven't really found those types of situations too much in the wild (tons of array math etc.), and if so they can often be simplified via jQuery or the like anyway.

So yea if it works for you, great, but I am glad whitespace syntax is not de-facto in the js world. I think js should remain as Java is -- other languages can be built on top of it with their own syntax types but developers still have the choice to ignore these supposed advancements & cherry-pick the ones they like (in my case progress in pure js + Dart will be where i focus my learning).

> i instead have to obsess over this tidying

I don't mean this as a personal attack, but your comment contains plenty of spelling errors, incorrect punctuation and capitalization, and inconsistency (e.g., use of both "&" and "and"). In my experience, people who aren't careful with syntax tend to detest significant white space, which is understandable.

I would agree that the indentation in CoffeeScript causes confusion, especially since the recommended size is 2 spaces.

I don't think indentation is a problem particularly. Once you're familiar with languages that use it, e.g. Python, it gets pretty natural. I did run into problems with the 2 space indentation, however, because with certain character combinations, it's difficult without a second look to be sure.

I would argue there are bigger problems with CoffeeScript, such as empty blocks being legal. For example:

    if foo
Is totally legal. But 99% of the time, you really mean:

    if foo
In Python, the former is a syntax error and there is an explicit pass call to demonstrate that the block is empty. But in coffeescript, it's easy to accidentally write that code and it looks right when you're doing a quick read through. Again, I think 4 spaces would help as you would be expecting a larger indentation.

That's not legal in CoffeeScript either. I just tried it on the CS website and got the message "ERROR ON LINE 1: UNEXPECTED POST_IF".

That might be new. We definitely had a bug in earlier versions of Trello due to that, so it stuck out in my mind as one of the places that Python did it better.

Does anyone know of any text editors that have vertically spanning highlight bar to show clearly where your cursor x-position is from the bottom of the page up to the top? I think it would help with matching up indentation especially in CoffeeScript.

I don't know any worthwhile editor that can't show tabs.

The author uses CoffeeScript for completely different reasons than I do. While a lot of the convenience features of CoffeeScript are awesome, I use CoffeeScript more to compile JS to standards-compliant, consistent code. Variables are hoisted, commas are automatically inserted, semi-colons are taken care of, and the entire script is put into a lovely self-invoking function that helps fool-proof things.

Furthermore, because CoffeeScript requires (sort of) a compilation step, errors are caught and debugging becomes MUCH easier than it ever was with plain JavaScript. Most text editors now have plugins that will compile selected text to JavaScript so you can preview the end result and make sure that you're getting the output you want.

The better part? When JavaScript best practices evolve, CoffeeScript can evolve with it, but the code can more-or-less stay the same. Awesome!

I couldn't agree more.

Unlike the author, I love significant whitespace and am enjoying nimrod lately with it.

I'd love to see a CoffeeScript variant for TypeScript. TypeScript has the structural things of CoffeeScript and more (OO paradigms, member visibility, modules, typing, etc) but much more verbose. I have tinkered w/ the CoffeeScript grammar/parser adding in a backslash to denote to type (e.g. "(x\int) -> x * x") and the TypeScript AST and compiler are very easy to work with. I just haven't had the enthusiasm to build a complete project. That would be my dream language. Until then I think scala.js is a great fit.

I love CoffeeScript and am excited about nimrod, but I don't see the point of TypeScript. Honestly I am fairly certain that it was largely created by Microsoft as part of the EEE strategy (http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish) since the main advantage of JavaScript is not having to supply types.

I disagree. TypeScript not only attempts to be inline w/ upcoming ES/Harmony standards, but it is not pushed on you in any way. It's Apache licensed and it's not like MS is putting a TypeScript VM in their browser. I love TypeScript's typing system, especially type declarations which are based on whether something has something vs on its named type (i.e. duck typing). There are many editors from MS's free VS express to WebStorm plugins to event IDE's written in TypeScript themselves. I find the language work by MS these days (this, f#, etc) to be really community friendly as opposed to locking in.

Re "main advantage of JavaScript is not having to supply types", I am a static typing fanatic so I am just going to disagree here and spare everyone the religious (or as Yegge would say, political) war.

> since the main advantage of JavaScript is not having to supply types.

With TypeScript and Dart, the type annotations are optional. You don't have to use them.

With JavaScript, you can't add any type information. Using non-standard doc comments is the only option.

Also, the main advantage of JavaScript is that it's available in browsers.

I don't do a ton of js programming, but I did poke around with cs a bit. For me, clean iteration seemed like the biggest win. And then I discovered underscore/lodash. So I don't do as much cs anymore.

Essentially, js isn't all that busted. The busted parts can for the most part be worked around with underscore/lodash and sweet.js (for the really ambitious)



pretty neat pattern matching library written with sweet.js


I do most of my work in Python, so the above experiences and biases may be a direct result thereof.

I gave CoffeeScript a shot, and frankly I don't like these JS "wrapper" languages.

First of all if you want anyone else to help you with your code its likely that they don't know the wrapper's syntax and will have to waste a bunch of time learning it. My boss got super excited about it when it first came out and it just caused a lot of headache and wasted time. First I (and all my coworkers) had to learn the language, and then port all of our existing code to CoffeScript. And for what? Some syntax sugar?

Honestly, I don't really see any problems with Javascript's syntax. It's everything else.

> will have to waste a bunch of time learning it.

Please define "bunch of time". I'm having trouble imagining how learning CoffeeScript would require more than a couple of hours for an experienced developer.

A couple of hours is a quite a bit of time IMO. Especially if there's alot of people that need to learn the language.

I mean, obviously a few hours isn't honestly that much. But in terms of the actual benefit you're getting by learning CS makes it not worth it at all. Workflow improvements are negligible (if anything, it probably worsens your workflow because of the extra compilation step). There's no compelling performance enhancement. You aren't getting any real benefit from learning CoffeeScript other than some feel-good syntactical sugar.

> [tooling] is perfect with JavaScript

Tooling is terrible with JavaScript. Even if you use something like Tern, it's still really bad.

You can pass arbitrary arguments to functions. Types and arity isn't checked. Optional positional/named arguments (with default values) don't exist. Passing some options object and "foo = foo || 5" is the best you can do. You can't tell, with absolute certainty, that some object doesn't have some particular property. A string might have a "lenght" property (should have been "length", that was a typo).

Your IDE can make some educated guesses and offer some auto-complete suggestions based on that.

There is also type coercion. Maybe you really wanted to create NaN in a very elaborate manner. Multiplying some array with some object is totally legit. No squiggly line for that.

That's a far cry from being perfect.

Never used something like C# or Java? Dart's tooling is also pretty good, for example. Even AS3 offers much better tooling than JS. TypeScript does of course also offer way better tooling.

JavaScript's tooling is terrible, really.

My point is JS tools work with JS as intended, and work with CS to varying degrees of success and with a variety of ways they handle CS. I was a C# developer for many years, so I know what I'm missing.

Also relevant: a big question is how CoffeeScript is going to deal with ES6 and the overlapping syntax between ES6 and CS, which may involve breaking backwards compatibility or leaving out ES6 features.


jashkenas > So in general, what I'd like to see mainline CoffeeScript do, is adopt useful ES6, ES7, and ES8 features, as soon as they land in enough platforms/browsers to be widely useful (yield may be at this point already, or very soon), and to continue to try and find a pleasing minimalist syntax for writing and reading them. If this means taking the ES* syntax wholesale, that's fine. If it means minting a new (and hopefully, but arguably, nicer) syntax, that's fine too. And if it means breaking backwards compatibility, that's also alright, as the compiled lowest-common-denominator JS output will still be perfectly compatible with the new stuff.

> If you’re contributing to the JS community, you’re better off writing in JavaScript. More people will contribute and/or adopt your code.

Quality, not quantity. Maybe the higher quality contributors are more likely to get excited about a cs project over js.

Initially I got excited about CS, until I discovered that it forbids shadowing and conflates variable declaration with assignment at the same time, leading to random bugs happening all over the place as I introduce a name that I've used somewhere in a deeper scope. No, identifier names are one of the big problems of all languages and CS gives you even less name locality. Bad.

I'd argue that that's a feature. You're asking for decreased code comprehension and bugs when you start using identical variable names everywhere.

I have noticed a lot of "Issues" in the CoffeeScript repo from angry hackers that were mad that CoffeeScript forces them to code with some modicum of responsibility (no drop-throughs in switch statements, no var shadowing, etc.). Doesn't make sense to me why people would blast JavaScript for letting you do stupid shit then get butthurt when a solution takes those same problems away.

No, I'm not asking for bugs. I'm asking for a basic feature of natural languages: to define a context where I work, where short, concise words have a precise meaning. This is an elementary thing - its the basis behind namespaces, the drive behind object oriented programming. Its a fundamental design mistake to put limits on this.

But its worse, because its also a silent mistake. Shadowing could be forbidden but variable declaration and assignment could still be different things, and then the compiler could warn you when you try to re-use a name. But no, coffee script will give you random bugs instead.

JavaScript has its rough edges. CofeeScript simply has a rot right in its core.

I found it helps clear up your naming habits and avoid short names, which are a major source of opaqueness in code.

On the contrary, short names are a source of clarity and expressiveness. Humans convey so much information through context, and shadowing nicely allows us to at least approximate that.

But I would be okay with this stance (yet would not use coffeescript) if the language had a mechanism to warn you when you're trying to reuse a name. Instead the language's features combine in a way that will clobber your code and lead to subtle or not-so-subtle bugs.

That would be true if there wasn't a very vocal swath of developers that won't even use a CS project out of prejudice, much less contribute to it. I don't know why that religious war came to exist, but it's the unfortunate reality.

In their defense, it is a fairly different language. It's not something that most JS developers I've seen trying to learn it can pick up just from reading it; they have to look at the docs and then practice parsing/writing it and then look back at the docs, etc.

Maybe, but many JS programmers won't touch anything CS.

In my experience, the most prolific and arguably best JS developers are mostly anti CS.

Can anybody explain some good use cases of implicit return? When I was doing a project in CoffeeScript last year (the only time I've used it), I found myself just using the return keyword explicitly because it was more readable, and I never ran into the issue the article talks about where it can be bad to accidentally return something from a function that should return null/undefined.

When would implicit return make code better? Maybe I'm answering my own question, but I can see them being more readable to somebody coming from a Haskell or LISP background than to somebody like me who has worked mostly in C, Java, and Python.

> I can see them being more readable to somebody coming from a Haskell or LISP background than to somebody like me who has worked mostly in C, Java, and Python

Ruby also has explicit returns. The idea is, every statement is an expression, and so has a return value. You don't need to figure out about whether a statement does or not, it just always does. One less thing to have to think about.

Other things, too, but that's one that that sticks out for me.

I have similar issues with coffescript, specifically the pain of significant whitespace is noticable whenever I find myself recalling how to write a simple `setTimeout` (or any similarly structured function) calls correctly, which is pretty much every time I use one as I don't find it particularly natural or intuitive.

Personally, though I'm looking at Dart rather than ES6.

This is how I do setTimeout:

  delay = (ms, func) -> setTimeout func, ms
So you can write it like this:

  delay 100, -> console.log "100 ms passed"

The problem is it isn't the only situation this comes up in, and the fact that this has to be done at all is a testament to the problems with adding significant whitespace to a language not completely designed for it.

I hope coffeescript supports generators.

CoffeeScript is waning for me as well but not for the same reason: Dart and/or Typescript seem to be superior solutions, both backed by companies that are going to keep their language alive for a very long time.

I'm curious which one will emerge, though.

I avoided learning the fashionable thing for so long, now I'm fashionable!

the only thing from coffeescript i think i will end up really missing is switch expressions. When used with conditional assignment it makes for code that is far prettier and more concise than nested if-then-else chains.

[1] https://gist.github.com/Vertice/ac357533da976990dc4d

I literally stop reading when he start whi..talking about hate on significant whitespace.

I literally hit downvote when he start whi..talking about whi..talking about hate on significant whitespace.

Unlike the whitespace in my code, your downvote is insignificant to me.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact