Hacker Newsnew | comments | ask | jobs | submitlogin
CoffeeScript: less typing, bad readability (ceronman.com)
344 points by dcu 580 days ago | comments


jashkenas 580 days ago | link

Most 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

-----

lowboy 579 days ago | link

Perhaps a style guide should be put up at coffeescript.org, or at least linked to.

-----

WickyNilliams 579 days ago | link

I 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

-----

mcgwiz 579 days ago | link

Perhaps a style guide should just be encoded into the compiler.

-----

bicknellr 578 days ago | link

I feel like CoffeeScript is failing at what it's attempting to do if it needs its own style guide.

-----

crazygringo 580 days ago | link

This 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.

-----

luriel 580 days ago | link

Magic overdose.

Compare with Go, where you can easily read the whole spec and keep the whole language in your head: http://golang.org/ref/spec

-----

deafbybeheading 579 days ago | link

Go is an excellent contrast. Not only is the syntax spartan, but--especially if you include the built-in formatter gofmt--it has a fascist insistence on a uniform coding style. I don't agree with all its stylistic decisions, but I'd rather live with them and have consistency than run into corner cases and gotchas.

-----

masklinn 579 days ago | link

I would not consider a 62 pages spec possible to "keep in your head", let alone easily.

The "The Smalltalk Language" section of the last ANSI Smalltalk draft is a more reasonable 28 pages.

-----

FuzzyDunlop 580 days ago | link

I think CoffeeScript seems nice in theory, but in the end, it's something made for people who want to code javascript, without actually using the language. It exchanges some of the terse, functional elegance javascript offers for a different kind of elegance, with its classes and inheritance and such like.

I won't say it's bad, as it is nice to work with when you're writing it, and I do quite like it. But I could never recommend it to someone who didn't have a good knowledge of javascript already.

-----

yesimahuman 579 days ago | link

I don't believe it exchanges any of the elegance. You can do the same things in CoffeeScript that you would in JS, just with less typing. That being said, a knowledge of how the browser will execute your compiled Javascript is crucial.

-----

TazeTSchnitzel 580 days ago | link

I 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 579 days ago | link

I 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/

-----

DasIch 579 days ago | link

Indeed but they obviously seem to apply to CS as he has shown in his examples.

-----

paul-woolcock 579 days ago | link

Oh, I agree, it was just surprising to me to see them there.

-----

orangecat 579 days ago | link

Right. I've started using CoffeeScript for a side project, and I really appreciate how it fixes most the warts in JS, but I wish they had stopped there rather than making gratuitous syntax changes. Parentheses in function calls is not an actual problem.

-----

jashkenas 579 days ago | link

I'm afraid that in conjunction with significant whitespace, they're not at all gratuitous. For example:

    describe 'Calculator', ->

      it 'can add two positive numbers', ->
        result = calculator.add 2, 3
        assert result is 5

      it 'can handle negative number addition', ->
        result = calculator.add -10, 5
        assert result is -5 
Mandatory parentheses make significant whitespace lose much of its appeal when passing a block construct into a function. This is a large part of the reason why Python limits lambdas to a single line...

-----

masklinn 579 days ago | link

> This is a large part of the reason why Python limits lambdas to a single line...

Python doesn't limit lambdas to a single line, but to a single expression. That is a rather different constraint.

-----

jashkenas 579 days ago | link

Sorry for the imprecision. It's the same thing to Python, in terms of significant whitespace. Language features that use whitespace for structure are not considered to be expressions, and can't be used as part of a larger computation. In CoffeeScript, they are, and can.

-----

orangecat 579 days ago | link

Valid point. Although I'm on the fence about significant whitespace in CS as well; I value fixing JavaScript's glaring flaws much more highly than arguably more convenient but unproven syntax. (The boundary is admittedly fuzzy, e.g. list comprehensions).

-----

politician 579 days ago | link

Optional parentheses wouldn't be so irritating if the rules for omitting them were universal. Currently, when calling functions with arguments you can omit the syntax, but when calling functions without arguments you must use parentheses. Could the 'dispatch vs variable reference' question be decided with some sort of suffix that preserves the value of whitespace? Something like 'f!' 'g! arg1, arg2'?

-----

lowboy 579 days ago | link

As I wrote in the other recent CS thread here, I think your coding style must be ill-suited to coffeescript. I've had a few situations where I've had to test things out for myself, but nothing like what you put forth. I just write CS as I would JS and that's that.

To that end, the docs on Coffeescript.org are the reference documentation (as they are the only official documents to reference) and they've suited me just fine. I get the sense that you're looking for a document in the style of ECMA-262, rather than one in the style of MDN.

-----

johnbender 579 days ago | link

I think it would be interesting to see the operational semantics for a very small subset of the language. Applying that type of formalism would likely suss out or highlight the corner cases like the ones highlighted in the article.

-----

no_more_death 579 days ago | link

Maybe coffeescript programmers could just use their brain and choose not to descend the Infinite Staircase of Obfuscation (the carrot's not worth it). Just because Coffeescript can saw your foot off doesn't mean you have to.

-----

johnx123-up 579 days ago | link

I have used CS on 3 projects and Scala in 2 projects. For me, both CS and Scala have terrible readability. Scala is more worse, I'll need at least 3x to read it than write it. Obviously, YMMV (tm)

-----

smacktoward 580 days ago | link

I 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/), with a "JavaScript mindset"? Truly, it is a mystery.

-----

tikhonj 580 days ago | link

So is mathematical notation not readable? On the one hand, it takes quite a while to learn how to read it. On the other hand, it can condense literally pages of text into a few equations which somebody experienced can understand almost at a glance.

The same is true for programming languages. Sure, anybody can read Python. But it's fairly verbose and attempts to mirror English. On the other hand, Haskell is somewhat terse and attempts to mirror mathematical notation. I've found that, after about the same amount of time with either language (about a year of off-and-on use for both), Haskell becomes far easier to read than Python.

So just because something is easier immediately does not mean it is any more readable. It could, in fact, be less readable and merely more familiar!

-----

rdw 580 days ago | link

Mathematical notation is not readable, no. It requires extensive training to be able to understand it, and even experts will take quite a while to comprehend a document they are not already mostly familiar with. It is not like you cross some threshold and immediately become able to understand all mathematical notation with equal ease. There's plenty of evidence for this; recently we had this quote about the ABC theorem: "It can require a huge investment of time to understand a long and sophisticated proof, so the willingness by others to do this rests not only on the importance of the announcement but also on the track record of the authors" (http://www.nature.com/news/proof-claimed-for-deep-connection...)

Other examples that highlight how understanding of mathematical research involves much more than just reading: https://docs.google.com/viewer?a=v&q=cache:5NM3XjxAWfUJ:... http://math.stackexchange.com/questions/13460/how-to-read-a-...

-----

lloeki 579 days ago | link

> even experts will take quite a while to comprehend a document they are not already mostly familiar with

Experts don't take time to read notations. They take time to understand the full scope of consequences embedded in a line composed of such a condensed and readable notation, within the frame of an otherwise complex proof.

> Mathematical notation is not readable, no.

I beg to differ. You mention the recent possible proof of the ABC conjecture, and I happened to browse through various materials on the subject. While I am far from being able to understand the crux of the proof, I can perfectly read the various components of it. In fact the notation system is so readable it actually helps tremendously in grasping concepts previously unknown to me.

-----

bcoates 580 days ago | link

Mathematical notation is much harder to read than prose. It does a very good job of serving as a mnemonic for something you already understand, and a very poor job of explaining novel (to the reader) concepts.

It's also as bad as natural language for ambiguity and informality.

I don't think either English text or mathematical notation is a magic wand for readable programming language; It's more about reducing accidental ambiguity and the amount of mental context needed for parsing 'natural' constructs in the language.

-----

mmcnickle 579 days ago | link

Personally, most of the benefit I see from mathematical notation is down to pattern matching -- "Oh, this looks like a Fourier transform". The idea seems to be supported by the fact that there is a unwritten convention for which symbols to use for which concept (alpha over beta for example) and the way in which the equations are laid out.

-----

tjholowaychuk 579 days ago | link

this^

-----

masklinn 580 days ago | link

> 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 580 days ago | link

Not 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 580 days ago | link

Or, 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.

-----

lmm 579 days ago | link

Mere consistency is not enough. List is hard to read because humans do not have a natural feel for how deep a set of nested brackets are, and you have to be able to spot the matching open-bracket to understand the code.

-----

wonderzombie 579 days ago | link

Again, it's hard to read if you are not familiar with it. Even as someone relatively new to Lisp, indentation and formatting makes a world of difference for readability.

This isn't specific to Lisp, either. I posit that if you took your average C-like and removed indentation from any reasonably sized function or method (one or more loops, one or more if/else), you would have a hard time counting brackets.

-----

wonderzombie 579 days ago | link

I agree that consistency is necessary but not sufficient, though, which is what I think you're getting at. Most of the time, though, consistency is clearly better than inconsistency. There's less to remember or, if you prefer, less to screw up. :)

-----

masklinn 580 days ago | link

Please note that I was not replying to TFA, I was replying to smacktoward's assertion that if you need to learn how to read a language it's not easily readable.

-----

wtetzner 580 days ago | link

> If you have to take the time to learn how to read something, it's not easily readable.

What? What language can you read without knowing it first?

-----

smacktoward 580 days ago | link

If you're used to one C-style language, it's generally not hard to read code written in another. This is not to say that you'll grok it 100% accurately on your first go, but another C-style language will be more readable to you than, say, a Lisp-flavored one would be.

-----

Evbn 580 days ago | link

Of course that "readability" leads to devs writing C in Java, or what have you, and naking subtle mistakes, instead of learning the new language. See Dijkstra's "On the cruelty of really teaching computer science"

-----

jaequery 580 days ago | link

i'll stick to javascript. coffeescript doesn't add a whole lot to the table, javascript is the standard and that's a good thing, re-writing the language is not the answer in my opinion. i'd have to imagine that saving a few keystroke might sound sexy to lesser experienced developers, but that really is all it adds to the table. being able to code on any project immediately off the bat with a standardized language is a huge plus, in terms of flexibility and scalability. you don't want to limit your company to exotic language, only to later find out few months later another new language called "frapscript" is now the new cool thing to do.

i recall the days when i was thrown into a project where the requirement was to use mootools, rather than jquery. even though they are both "javascript" in nature, it severely limited my productivity. i can see the same thing happening to companies trying out coffeescript, it may seem like you are doing the better thing long-term wise, but in reality, it is not so much. it's better to just stick to standards and you'll be more productive down the line, i can almost guarantee it.

-----

agscala 580 days ago | link

I'm not the hugest fan of coffeescript, but I don't know if you can consider it to be an 'exotic' language at this point. It's quite widely accepted.

-----

jaequery 580 days ago | link

on which metric do you base it on, to be widely accepted?

-----

agscala 580 days ago | link

Looking at github's top languages, it sits at #11. I thought it was higher than that, but it's still nothing to sneeze at.

Maybe saying it's widely accepted isn't entirely appropriate, but it certainly is gaining a lot of traction.

-----

deanotron 579 days ago | link

I'm not sure that this will ever be a fair statistic because coffeescript should never really be used for shared / module code IMO. I love CS for my application code but would never release a package on github in CS, only JS.

Once you are releasing things outside of your controlled/team environment using anything but JS is just a loop for others to jump through.

-----

lowboy 579 days ago | link

I imagine a lot of projects have both CS source for development, with compiled JS for deployment. That might skew the stats between JS+CS, but it's a good indicator of CS' popularity compared to other languages.

Considering that, releases would be in JS, as they should be.

-----

encoderer 580 days ago | link

Your last paragraph confuses me.

So you had jQuery experience and were inhibited by working on a MooTools project. I get that, makes total sense.

But then you say that switching to CoffeeScript may seem like a better long term choice but "in reality it is not so much."

Surely MooTools would've been fine for you as a long term choice.

Yes, there is a penalty to switching. Whether it's jQuery to MooTools, JS to CS, whatever. But that doesn't make it a bad long term choice.

Also, CoffeeScript is more than just saving keystrokes. That makes it seem like it's all about initial up-front cost savings. Instead, it's about having shorter, more expressive code. That pays dividends for the life of a project.

-----

jaequery 580 days ago | link

"Instead, it's about having shorter, more expressive code."

yes, but at the expense of a lot of other negative baggages that comes along with it. by having it's own compiler rather than leaving that to the browser seems like it's opening a can of worms.

and just reading from the comments, i can see how we could soon see a birth of "another language", that's supposed to be solve all problems coffeescript'ers face.

for one, i guess readability seems to be the common problem, which isn't good for productivity.

-----

SoftwareMaven 579 days ago | link

i can see how we could soon see a birth of "another language", that's supposed to be solve all problems coffeescript'ers face

That's called incremental progress a d most people see it as a good thing. Others yell, "Get off my lawn!"

-----

encoderer 579 days ago | link

It sounds like you haven't ever used CoffeeScript?

Don't you find it a little odd that you have such strong opinions on something you've never even tried?

-----

ricardobeat 580 days ago | link

There's a bit of a contradiction in your statement. MooTools is much more idiomatic than jQuery in it's use of javascript inheritance, object creation, etc, so it's "more javascript". jQuery is so efficient to work with because it created it's own nice DSL, not because it is standard. The standard could be C, would that make you more productive too?

-----

jaequery 580 days ago | link

it was a point that even if you are merely switching a js framework where both are written in javascript, productivity can drop.

if you now switch to coffeescript, something not remotely close to javascript or any other languages fwiw, you'll experience un-productivity. it's akin to having your top developers walking in eggshells and doing nearly nothing close to what he is capable of.

i think coffeescript is great in the sense that we are trying to create a better language. but i also sense how much damage it can bring to budding startups who can't find talented coffeescript'ers to fill the void when their lead developer moves on to other things.

a one off go project, i'd say it's fine. but anything more complex, i think you'll see programmers wishing they had gone back to what they were familiar with.

-----

ricardobeat 579 days ago | link

What damage? You can drop it at any minute and start working on the compiled javascript. I've done this a couple times.

That's true for any tool/language/platform/whatever, everything has a learning curve (and coffeescript's is quite short). Going by your words we shouldn't ever learn anything.

And you shouldn't switch to a language if your developers are not comfortable with it. Do some experiments, try it out on a smaller project, then you might switch if you see good results.

-----

ilaksh 580 days ago | link

Just 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

-----

joemoon 579 days ago | link

> Just 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.

Isn't this precisely the problem? Why make a better Javascript then make the same mistakes as the original? One of the main goals is for Coffeescript to be more readable that Javascript. Having ambiguous syntax and so many different ways of doing things means that people will write code in all of these different ways.

Your rebuttal is a long list of what you SHOULD and SHOULDN'T do, but there are two problems:

1. Not everyone will agree with you.

2. People will write it the "bad" way anyway.

Ultimately this means less readable code, especially when you have to read someone else's code.

-----

Contero 579 days ago | link

> 2. People will write it the "bad" way anyway.

People will write bad code in every programming language you give them. I don't see that as a justification for limiting the expressiveness of a language. If you take that line of reasoning too far you end up with Java.

-----

joemoon 579 days ago | link

> I don't see that as a justification for limiting the expressiveness of a language.

That's a straw man. I never said that the expressiveness of the language should be limited. There are plenty of languages that are just as (more?) expressive than CoffeScript without the syntactical ambiguity.

> If you take that line of reasoning too far you end up with Java.

That's the slippery slope fallacy. I am in no way suggesting that CoffeScript should have completely rigid syntax. Surely there is a happy medium between CofeeScript and Java. There are plenty of languages that live there.

-----

lmm 579 days ago | link

Or python, which is where the author is coming from. In python there are fewer syntactic ways to write the same thing (semicolons aren't optional, they're just not permitted. The only ways to write and and or are 'and' and 'or', '&&' and '||' simply don't exist. Map literals always look like {key1: value1, key2: value2}, the braces are non-optional ).

Even python's critics would admit it's a very readable language, and it would be unusual to claim it's not expressive.

-----

jmmcd 579 days ago | link

A nitpick: you can use semicolons in Python.

    x = 3;

-----

bunderbunder 579 days ago | link

The slope slips both ways. If you don't take that line of reasoning far enough you end up with Perl.

-----

darkarmani 579 days ago | link

> as a justification for limiting the expressiveness of a language

Is it really more expressive just because there are N ways to do it?

-----

mcgwiz 579 days ago | link

Exactly. Expressiveness refers to the realm of problems a language can idiomatically address, not the number of ways a particular unit of logic can be equivalently written. If that were true, you could simply add any synonym for "if" ("when", "whenever", "assuming", "given" etc) to a language and claim the most "expressive" language.

-----

victorlin 579 days ago | link

Agree. When they invent a new language to fix some problems of the old one, if same problems (even more) appear in the new one, then why you need the new one? That's funny they try to fix some traps by introducing more pitfalls. What's the point? Those problems can be avoided by design, but they didn't.

In short, it was badly designed. Pointless to use it.

-----

mcgwiz 579 days ago | link

Also, his rebuttal doesn't defend the inclusion of those language features in the first place. If you simply "shouldn't" use a particular feature (e.g. if at the end of an expression), why should it be in the language at all? It shouldn't, ergo the language is nonsense, which was the original claim.

-----

thezilch 580 days ago | link

So, in short...

In CS, assign everything to a var, because good luck parsing CS tokenization.

In JS, assign a few things with a keyword or explicitly to a namespace, because good luck with global state(s).

Unfortunately, only the later is recommended, while the former is NOT and discouraged in lieu of being so verbose like the later. sparkles

-----

ilaksh 580 days ago | link

The last example I assigned the results to a var because it was doing a huge amount of work, any of the steps could fail, and it was just a lot clearer that way.

You don't always have to assign things to vars.

If you have two or more function calls on the same line, use parentheses after the first one. Or use parentheses in all of your function calls. Its just an advantage for some people to be able to leave the parens out because it is a little more readable for them. Otherwise, you can just write it the same as you would in JavaScript.

Scope is another big advantage of CoffeeScript.

-----

thezilch 580 days ago | link

You had more than one example of pulling out "anonymous" objects from a call, because that is "how it's done." The point is that it is ridiculous that one must go to these lengths to help parse a language, especially when it flies in the face of the language's doctrine.

Same goes for parentheses "here or there but not there, sometimes." This may very well be the anathema for those that don't understand the claims that ";" or "function" or "}" are real burdens.

-----

shardling 579 days ago | link

It doesn't go against the language's doctrine. The guy who invented it explicitly recommends pulling out anonymous objects and functions if they're not super trivial.

-----

mnutt 579 days ago | link

While I agree with your points,

    doSomething () -> 'hello' just isn't valid code.
Is valid code. Not that you'd ever actually want to use it:

    coffee> doSomething = (fn) -> if fn then fn() else (-> 'hi')
    doSomething = (fn) -> if fn then fn() else (-> 'hi')
    [Function]
    coffee>  doSomething() -> 'hello'
    doSomething() -> 'hello'
    'hi'
    coffee> doSomething () -> 'hello'
    doSomething () -> 'hello'
    'hello'

-----

coenhyde 579 days ago | link

Exactly, CoffeeScript isn't an excuse for writing incomprehensible code.

To make the OP assessment of CoffeeScript fair we would have to apply the same logic to Javascript its self. If we looked at any minimised JS code we would have to conclude that the language is unreadable.

-----

SeanLuke 579 days ago | link

> Just because you CAN do something in CoffeeScript doesn't mean you SHOULD, or should ALL of the time.

In 1948, Edward Murphy, Jr. an aerospace engineer, was working for the Air Force to install sensors to test g-forces on humans during deceleration. There were two ways to wire each sensor, and one of them was wrong. Someone had methodically installed every single sensor backwards. Murphy quipped something -- no one is exactly sure what it was -- which was cited in the Aviation Mechanics Bulletin as "Murphy's Law: if an aircraft part can be installed incorrectly, someone will install it that way." A few mutations later and this became the famous "Murphy's Law".

I think the original Murphy's law applies with great force to the world of programming languages. If there are multiple ways of doing something, and some of them are stupid, you still have to know all of those stupid methods because some idiot on your team will do it. The probability of this happening increases as the size of your team increases.

The proper course of action as a language designer is to make sure that foolish methods are not built into your language. What you do not do is design foolish methods into your programming language, and then put up a big sign on Hacker News saying "don't do that".

The Original Murphy's Law is so critical to the design of systems -- languages, APIs, libraries, etc., that after your post I feel compelled to ask you to put down your Programmer's Card and step away from the keyboard at this time.

-----

ilaksh 579 days ago | link

Right because programming is just like installing parts into an aircraft.

Since you are obviously an expert in programming language design, I am curious to know, what programming languages have you designed?

He made it flexible in order to appeal to people who want a functional programming style and like to be clever. I don't want to deal with that type of code especially but some people actually prefer that way if that is the way they have been programming for a number of years or if they are just looking for something new.

"Put down your programmer's card" -- very uncalled for.

Any language can be abused or used in styles that are difficult to read or maintain. Almost all languages that I have seen have more propensity for that than CoffeeScript.

This one of the best language designs ever because of the significant whitespace (which to me is logically the most obvious rebuttal to your comment), small amount of required punctuation, intuitive and practical keywords, solving many of JavaScript's problems, appeal to Ruby enthusiasts and functional programmers which represents a sizable chunk of the best software engineers in web development, and compatibility with JavaScript. In order to do all of that it needs to have the flexibility that we are discussing.

CoffeeScript allows for the closest thing to my pseudo-code that I have seen.

Anyway I have spent way too much time on this discussion already.

-----

SeanLuke 579 days ago | link

> Right because programming is just like installing parts into an aircraft.

...

> Since you are obviously an expert in programming language design, I am curious to know, what programming languages have you designed?

...

> Any language can be abused or used in styles that are difficult to read or maintain.

These were three classic fallacies in a row.

As to the second one (ad hominem demands of authority): an in argument, it is never classy.

That being said:

> "Put down your programmer's card" -- very uncalled for.

That was meant as a joke but I can see that it might deservedly cause offense. And so I rescind it and apologize.

-----

tjholowaychuk 579 days ago | link

"coffeescript: the good parts"

-----

masklinn 579 days ago | link

> Indentation is significant in CoffeeScript, just like it is in Python. Just having a parenthesis shouldn't change that.

Er... in Python, having a parenthesis does change that, within parens Python uses continuation lines which are not subject to the same restrictions as free-floating code.

-----

aes 579 days ago | link

  > doSomething (->
  > 'hello'), 1
> Indentation is significant in CoffeeScript, just like it is in Python. Just having a parenthesis shouldn't change that.

The point, I think, is that the example above should be an error instead of compiling into something you wouldn't expect.

Here's a syntax I've seen a lot:

  doSomething ->
      'hello'
  ,   1
or even

  doSomething ->
      'hello'
  ,
      1
That style is also handy to construct a long list of object literals.

> This is called destructuring assignment,

I think destructuring assignment is something else entirely. http://coffeescript.org/#destructuring

> its probably better to use isnt instead of !=, although rather than !=, you would want !==

'!=' is equivalent to 'isnt'. And '!==' is not CoffeeScript at all.

-----

klapinat0r 580 days ago | link

Exactly this. Thanks for doing a nice writeup.

-----

kin 579 days ago | link

wow thanks for writing this all out. i was going to tackle a few of the examples but it was going to take some time. my thoughts exactly. a lot of the examples no one would do and not even the coffeescript page documents it like so. some other people are right though in that there isn't any discouragement so far in writing things certain ways.

-----

crazygringo 580 days ago | link

Question: 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?

-----

jashkenas 580 days ago | link

Postfix conditionals are pretty nice for conditional statements that are particularly unlikely to happen. Imagine, in a function body:

    read(file)
    write(file) unless terriblyUnlikelyThingHappens
    return results
... it helps to keep the expected main-line flow of your instructions reading smoothly -- much the same as the way you'd tend to use it in English. Doing it the "normal" way instead:

    read(file)
    if (!terriblyUnlikelyThingHappens) {
      write(file)
    }
    return results
... makes it a bit more difficult to follow what should be going on in the function.

-----

OriginalSyn 580 days ago | link

I personally find that I end up reading more lines of code than I need to.

When scanning and I see

    If (condition) { perform_some_action(foo, bar, baz); }
And I know condition is false I can ignore what follows but

    perform_some_action foo, bar, baz if condition
I now have to stop and parse the entire line. But not only that, because it can appear at the end I need to parse every line to make sure I don't get caught by some if or unless. Short lines are easy sure but it's still annoying to me.

-----

ricardobeat 580 days ago | link

That would make sense if you were executing code in your head, but if you're reading you want to read all of it anyway...

-----

Jare 579 days ago | link

Not at all true, most of the time you are reading code with a specific goal or area of interest in mind, and thus are only interested in the subset of code related to that purpose.

-----

epidemian 580 days ago | link

But @OriginalSyn has a pont. If you are reading code because something is misbehaving on a given configuration and you read

  if (some condition that doesn't hold on that configuration) ...
You can avoid everything inside that if statement if you know that's not important for the case you're considering.

-----

mayanksinghal 579 days ago | link

But if we want to avoid it, we would be required to already know what's inside the parenthesis. If we already knew what's inside it, putting condition before helps more as in that case (1) Either it's true and you have to parse the block or (2) It's false and you just jump to the end of it.

-----

tjholowaychuk 579 days ago | link

yeah I agree here as well, postfix anything is quite annoying to read, especially so when chained, and the absence of parentheses makes this even more terrible

-----

evanmoran 580 days ago | link

I 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 580 days ago | link

Though, 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 579 days ago | link

It'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 579 days ago | link

Those are good points. I'd probably make it multi-line:

    if badness
      throw 'error'
    
    unless goodness
      return null

-----

aes 579 days ago | link

If may be strange because of the asymmetry but I'd actually prefer `if` to be come first all the time and `unless` to come last all the time - precisely because `unless` reads like it's for exceptional circumstances:

  value = cache[key]
  if value?
    return value

  return file.readContents() unless not file.exists()

-----

natefaubion 580 days ago | link

I find it helps when you use short-circuiting. The returns are the first thing you see, making it more obvious what is going on.

  myfn = (arg) ->
    return 1 if arg is "one"
    return 2 if arg is "two"
    return arg.toInt()
This is obviously a little contrived with such a short method, but helps when you have stuff to do between conditional returns.

-----

epidemian 579 days ago | link

Yeah. The example is not very good, as it would probably be better to write as switch expression. But on a complex function, returning early can avoid the need to retain a lot of context in your head while reading that code. I find it especially helpful for returning/throwing on error conditions or breaking out of recursion.

-----

tjholowaychuk 579 days ago | link

+1 reads poorly

-----

ricardobeat 580 days ago | link

Though 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 580 days ago | link

I 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 579 days ago | link

See 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.

-----

More



Lists | RSS | Bookmarklet | Guidelines | FAQ | DMCA | News News | Feature Requests | Bugs | Y Combinator | Apply | Library

Search: