Eh. 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.
> "If you write terrible Coffeescript, it's hard to read"
No, it's "If a language that provides for many ways to write terrible code (incl many ways to write the same code), people will write hard to read code." For example if parens are required, it is impossible to "get clever" with not using them.
> No, it's "If a language that provides for many ways to write terrible code (incl many ways to write the same code), people will write hard to read code."
A prime historical example being Perl. A second one being PHP.
If writing good, maintainable code requires knowing/using a large number of rules and best practices that aren't part of the language (and whose absence are actually considered to be a virtue of the language), that seems like a flaw in the language itself.
Yes, you can write bad code in any language. That doesn't mean that languages don't have an impact on the ease of writing good and correct code.
If you think that the existence of style guides are a flaw in their respective languages, then I'm going to (as non-condescendingly as I can via text) suggest that you may not be a very mature developer yet.
Style guides and best practices exist for every commonly used language, and not because of flaws in the languages themselves, but because unless there is literally only one way to do things, a dozen developers will come up with a dozen ways of solving a problem.
There's a difference between style guides offering a well-lit path to follow, and a language having a large number of possible expressions that are off limits in practice because they lead to bad code. The former marks out a path, the latter indicates a minefield. When the language's design actually facilitates the creation of bad code, not just by offering the possibility of dangerously ambiguous expressions, but by touting that possibility as a plus, that's a flaw.
Maybe accepting that flaw is worth it because the expressiveness of the language makes it a net plus; doesn't mean it's not a weakness or flaw or a point to be cautious about.
I do apologize - I didn't mean to be perjorative. I meant to communicate that I've heard the sentiment ("why does it let me shoot myself in the foot? It shouldn't let me do that!") espoused by many, many new developers, and it's an attitude that I've seen many people grow out of.
Coffeescript is a very flexible language. Its flexibility lets you do bad things with it, but the flipside of that attribute is that you can do very good things with it. I don't think that it's either "a path or a minefield"; I think those are two sides of the same coin. Optional parentheses and whitespace delimiting can reduce visual clutter, but if you abuse them and reduce it too far, you increase cognitive load on the person that has to read and maintain the code.
The more stringent the language, the less guidance you need in the form of style guides and community standards, but that's simply because the language itself imposes those standards on you as a byproduct of disallowing flexibility. It's absolutely something to be cautious about, but it doesn't make the language inherently flawed.
Syntax flexibility is not a virtue. Creating restrictive rules about what I can do to an object or how functions work ties my hands when I try to do tricky things, but syntax only limits my artistic urges to do esoteric code layout.
The C style syntax situation with optional if brackets is almost universally considered a flaw:
if (foo)
st1();
st2();
This is not the flexibility to do hard things. It does not save a lot of typing or make some other common construct less cluttered. It is just a defect in the grammar that it's too late to fix.
It sounds like Coffeescript has more of these flaws.
I don't consider the optional braces in C-if a flaw. I use them for early return often, eg
if (somethingBad)
return NULL;
restOfBody();
And I find that the braces are often just unnecessary visual noise. Of course, there is always the issue of people adding extra statements, but I haven't found that to be a problem in practice. YMMV though
The trick to avoiding the problem of extra statements is to only skip the braces if it all fits on one line:
if (somethingBad) return NULL;
That's a clear visual indicator that the braces have been skipped, but it's basically impossible to look at the next line and not know that it's NOT part of the conditional. Also, if you're having trouble fitting it all on one line, it's a good cue that you're not in a situation where skipping the braces is safe.
I think there ought to be a distinction between semantic flexibility and syntactic flexibility, though. They may be correlated but it's not always clear cut. Lisp is an example of a syntactically inflexible (s-expressions or walk) but semantically rich language (macros).
My own opinion is that syntactic flexibility does have value (e.g. Haskell). I think it's also vastly overrated relative to that value; syntax is incredibly easy to bikeshed. Semantics require you to know something about the languages at issue.
That said, my opinion is that this kind of syntactic flexibility offers dubious value if the trade-off includes not just obviously broken programs but also subtly broken ones with errors which are difficult to spot. Newbie errors are part of the learning curve, but these seem like mistakes even experienced people can make.
> Its flexibility lets you do bad things with it, but the flipside of that attribute is that you can do very good things with it.
The problem is that there is a local maxima in the flexibility cost-benefit curve. After you reach that maxima additional flexibility degrades your experience.
But surely for a language that is almost purely designed to make syntactic improvements, the designer could have taken a stronger stance on syntax. I wish he could have at least decided on semicolons. The beauty of Python is that it is actually hard to write unclear code that does what you think it does. I'd love to see a PEP-8 for CoffeeScript or some kind fo built in linter.
Not saying that they don't exist, but I've literally never seen a python style guide (other than "don't mix tabs and spaces", which is part of the language now), never seen someone make a commit just to fix code formatting in python (something that happens quite often with every other language I use professionally), and never had any trouble working on other people's python.
No, sorry, omitting parentheses (because they're optional) can be "too clever". I love optional parentheses, but I feel like a lot of people omit them because they feel that they're supposed to, at the cost of code clarity. I'm arguing that you should omit them when doing so doesn't make the code ambiguous, but if you ever need them to improve code clarity, that you should use them.
The OP had a fine example of "doing it wrong", with the nested inner function call without parentheses. While technically valid, it's bad code because it's difficult to read, even for someone accustomed to optional parentheses. Such a construct is "clever" when it shouldn't be.
But then you have to think everytime whether you should put parantheses there or not. Is the code readable without parantheses? Should I put them there in case someone reads the code in a year and doesn't know about the problem domain ... ? It is not much, but it is extra cognitive load that is wasted.
It's akin to programming C and everytime you write a function, if statement or for loop you have to ponder whether it looks best to put the opening brace below the line or at the end of it. I hate reading code with an inconsistent brace placement style like that.
I agree with you in theory, but in practice when working on large teams, languages as flexible as CoffeeScript do become a problem. That's a major reason languages like Java and even C# are so inflexible.
For my personal projects or small teams I'd have no reservations using CoffeeScript if it felt like the best fit. For large teams, I'd reconsider.