6 ms·
My Take on CoffeeScript
- FuzzyDunlop 14y agoisLargerThanSix = if x > 6 then yes else no You don't need CoffeeScript to do something as redundant as that, since comparison operators return a boolean: var isLargerThanSix = x > 6 Of course, CoffeeScript doesn't even offer an improvement for the level of explicitness in the example, since it removed the ternary operator. This javascript is invalid CoffeeScript: var isLargerThanSix = x > 6 ? true : false
- ryanpetrich 14y agoif ... then ... else ... is the ternary operator in disguise.
- FuzzyDunlop 14y agoIt's not an improvement though. I find it pointlessly verbose.
- jrajav 14y agoAs opposed to pointlessly terse and cryptic?
- kaoD 14y agoCryptic? Are you serious? I'm a CoffeeScript user because I find JavaScript too verbose and cluttered and I find Coffee's verbosity quite unnecessary too. Without syntax highlighting skimming over Coffee code is awful because you can't distinguish code from variables easy enough. This is easier to read: a && b && !c Than this: a and b and not c The form with symbols is easier to process because you can clearly distinguish its parts. What's cryptic about ?: ? You learn it just like you learn if ... then ... else and that's it, not cryptic anymore. Not to mention the yes/true/on thing. What a waste of reserved words. Text-like does not mean comprehensible. If that was true, then we'd write Coffee like this: function sum with arguments left and right means the result is left plus right That's a lot less cryptic, right ?
- darkchasma 14y agoWell, if I look at C/C++, I feel that since & means a bitwise operation and && means a boolean operation, and & in front is a reference operator, that & is "Having a meaning that is mysterious or obscure" since the symbol changes in context. I also feel your semantic example is overly obtuse. func SumOf left and right is left + right -- result is SumOf left and right --
- kaoD 14y ago> I also feel your semantic example is overly obtuse. Exactly what I think of if ... then ... else IMHO, your plus sign is "pointlessly terse and cryptic". See what I did there? Now seriously, why func? I prefer Coffee's (arg1, arg2, ...) -> syntax for functions. What strikes me as odd is the fact that such a slim language gets verbose in such aspects. Of course my example is overly obtuse: it's just an hyperbole! But anyways, I suspect the if ... then ... else syntax is just a side-effect of ? being used as an existential operator in CoffeeScript.
- darkchasma 14y ago> IMHO, your plus sign is "pointlessly terse and cryptic". See what I did there? No, I don't see what you did there because + has one and only one meaning, and that is add. Every child can identify what + means, the same cannot be said for (a,b) ->, even to developers who have developed their entire lives (unless they have experience with coffeescript). Hence, cryptic.
- klibertp 14y ago> This is easier to read [...] Than this > What's cryptic about [...] ? You learn it [...] and that's it, not cryptic anymore. It's hilarious how you state some fact explicitly with your own words and yet completely fail to realize this fact. Readability is not to be confused with familiarity - and you do exactly this. You say that if you learn something it becomes readable, which is not the point, and not true at all. Think of readability as a measure of how many things you need to learn to understand something. If you introduce a symbol which meaning is completely arbitrary and needs to be learned, you make your code less readable. While Wikipedia page[1] concentrates on the readability of texts written in natural language, it suggests that the more words the text uses, the harder it is to read. The second part of readability is text length, and so sometimes introducing a symbol to represent common concept, while making it harder to read by itself, makes the program more readable as a whole because it makes the program shorter. It's a trade-off that needs to be considered when designing a language. The 'class' keyword in CS is a good example: it codifies a useful idiom, that in JS takes 5 lines of code, into a single word. While you need to learn it's meaning, which on the one hand makes the program less readable, on the other hand it reduces the length of certain class of programs significantly and so it makes them much more readable than JS counterparts. The 'if ... then ... else' is a bad example. The ternary operator does not reduce the length of any program significantly, especially in the presence of the 'switch' statement. Every time you use a ternary operator you still need a test, true expression and false expression. Ternary operator introduces the infix syntax, and not one, but two symbols that you need to learn. It's bad, really bad for readability. The code written like this: if (alive and kicking or dead) then (something) else (something els) is much more readable than equivalent: (alive&&kicking||dead) ? (something) : (something els) because the latter is not significantly shorter and it introduces as many as 4 (!) symbols with arbitrary meaning. You may not recognize this, because you already know the meaning of all of these, but objectively the latter form is less readable. Your statement that boolean operators are more readable as symbols than as words is simply not true, at least if we use the definition of readability from wikipedia. You are much more comfortable with these operators as symbols, you're more familiar with them and used to them, but that is something entirely different than readability. You think that it's readable, while it's not. I wish more people actually knew what readability is. Relevant info is just a click away, yet everyone seems to have his own definition of readability, which makes any discussion highly subjective and useless in the long term. [EDIT] Forgot to mention, this is exactly why I find discussions on Lisp or Smalltalk syntax so infuriating. People are not interested how readable the syntax actually is, that is - how many symbols it introduces and how many of them are reused in different places. They say that the new syntax is "unreadable", while it is much more readable than alternatives, just unfamiliar. [1] http://en.wikipedia.org/wiki/Readability http://en.wikipedia.org/wiki/Readability
- FuzzyDunlop 14y agoHardly, considering its appearance in many programming languages. Although I would argue similarly that, if the ternary operator is terse and cryptic and needs to be changed to 'if ... then ... else ...'; then '->' and '=>' are equally terse and cryptic and should be kept as 'function'. It says what it does then, doesn't it?
- anon1385 14y agoI agree but we need to go further and replace as many of the terse and cryptic operators as possible with words. Something like this but for Javascript: http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/...
- ricardobeat 14y agoHa. When I read that example I thought "poor guy, he should have chosen a better one, now this will be nitpicked to death". He is just demonstrating how `if` is also an expression, the comparison and return could be anything.
- insraq 14y agoYou are right. I should. This is definitely not a good example of showing "Everything is an expression" is CoffeeScript.
- tlrobinson 14y agoAs a CoffeeScript convert the ternary operator is one of the few things I prefer about JavaScript. There are better examples of "everything is an expression", like "for" loops and multi line "if then" blocks.
- crazygringo 14y agoFor what it's worth, this post nearly exactly mirrors my personal experiences with CoffeeScript. It's a great writeup.
- michaelwww 14y agoI'm glad to see you agree. I haven't had time to evaluate CoffeeScript, and now I don't need to make it because the advantages CoffeScript offers are not issues that bother me and it introduces issues that would bother me.
- tlrobinson 14y agoI wouldn't dismiss it so quickly. I dabbled with CoffeeScript for awhile, but didn't enjoy it until I used it full time for a week or two, and now I can't go back to JavaScript. The issues brought up in the article are annoying, but no more so than JavaScript's own annoyances (and in fact CoffeeScript fixes some of JavaScript's annoyances). After a couple weeks of using it you'll know what to watch out for an it will be very pleasant to use.
- betterimposter 14y agoYea, but the write-up failed to mention a few of the other advantages, most notably, comprehensions. Every time I do a for, map, filter, etc. in js, I wish I was writing coffee. Having said that, if the verbosity of array ops aren't a sticking point, then I say don't bother. I'd probably be just fine with js if I'd never typed dog.praise() for dog in dogs when dog.type is 'pet' I have gotten into the habit of singing these, so its probably just an oddity I have. Carry on and ignore.
- michaelwww 14y agoTo each his own. I quite happy with C-like languages with braces for blocks.
- tlrobinson 14y agoAnd your comment mirrors my experience with reading this writeup.
- stdbrouw 14y agoI don't really understand this "bad predictability" thing. If you leave out parens, CoffeeScript always wraps to the end of the line, simple as that. Hard to visually parse at first sight in certain scenarios? Use parens, that's what they're there for. Problem solved. I'd absolutely hate it if CoffeeScript was inconsistent in how it handled these things, but it really is not.
- jrajav 14y agoIf you have the time and inclination, you should write something up explaining this in more detail, with examples. This point is consistently brought against CoffeeScript in nearly every article about, even those for it, and it's one of the main things keeping me (and probably others) from giving it a serious look. Of course, it still wouldn't make up for the lack of a good spec and grammar...
- kaoD 14y agoNot to the EOL. a = b c d, e: 1 f: 2 Translates to: var a; a = b(c(d, { e: 1, f: 2 })); Though that's still predictable for me, I don't have problems with parenthesizing in Coffee (I did the translation off the top of my head and I'm pretty sure it's correct).
- insraq 14y agoEven though CoffeeScript handles this consistently, the difference is subtle and can be overwhelming for beginners.
- arnarbi 14y ago> set(User, function() { return {name: "John"}; }, silent: true); That's not even valid JavaScript, so I would not expect that. It is also somewhat standard that lambda-like operators eat as many tokens as possible. But I agree with many points. The anonymous function sugar is extremely handy in callback-oriented programming. I wonder if a small syntax extension to JS, consisting of Python like indetation and Ruby like blocks would ease the biggest pains: function f(some_param, callback) bla() return 1 f(10) |u,t| -> callback_code_here The call to f would receive the anonymous callback as its last argument. Callbacks in other positions, or multiple callbacks could be named: f(10, success, failure) succss: |data| -> console.log("Success!", data) failure: |error| -> console.log("Error: ", error)
- insraq 14y agoSorry, that's my bad, it should be { silent: true }. I translate myself and mix CoffeeScript into this. I guess that's a proof of the fact that I cannot live without CoffeeScript. I have corrected in the post.
- mratzloff 14y agoThis function f(some_param, callback) bla() return 1 f(10) |u,t| -> callback_code_here or f(10, success, failure) succss: |data| -> console.log("Success!", data) failure: |error| -> console.log("Error: ", error) are not simpler than valid CoffeeScript, such as f = (someParam, callback) -> bla() callback 1 # presumably your intent f 10, (u, t) -> # callback code here or success = (data) -> console.log("Success!", data) failure = (data) -> console.log("Error: ", error) f 10, success, failure
- arnarbi 14y agoI agree, and I don't want to simplify CS, but rather JS. The thing that bothers me about CoffeeScript is the call syntax without parenthesis but with commas - which seems to me the main source of "surprises". The main benefit of it however is allowing you to write anonymous function arguments without chasing closing delimiters. I would like something that lies in between JS and CS, with that particular benefit but without the weird grammar.
- deleted 14y ago[deleted]
- mistercow 14y agoI really don't find it hard to read. I'm much happier reading the CS that I've written over the last year than I ever was with reading the JS I've written. Sure, you can write unreadable CS, but it's easy not to.
- gildas 14y agoHow can you say that a language that is hard to read helps developers to be more productive? My experience in development shows that I spend more time to (re-)read my code than to write it.
- mistercow 14y agoWhile I love CoffeeScript, the always-implicit-return thing is my biggest pet peeve. The language really needs a non-implicit-returning arrow like -/> , if nothing else so that you can make one liners that don't return a value. Unfortunately, this isn't the direction they want to take the project in. The reasoning is that in CS, all functions should ideally have a return value. I think that's silly, since you have to contend with the fact that it's supposed to interoperate with JS, and plenty of builtins and JS libraries don't behave as if every function has a return value, but what can you do?
- masklinn 14y ago> it's supposed to interoperate with JS Definitely the crux of the issue, as languages/ecosystems where "callables always return a value" tend not to have that issue even when dynamically typed (Ruby, Erlang). And it's not just JS interop, but gateless interop: calling JS from CS or CS from JS is supposed to be "invisible" as opposed to e.g. ClojureScript which also has excellent JS interop but where the interop is done through special forms (e.g. the `js/` namespace calls into JS-global objects), managing developer expectations about the seamlessness of the boundary.
- mistercow 14y agoExactly, and the article's example is spot on for how these expectations get violated by CS's behavior. In CS, the assumption is that aside from minor (and easy to detect) performance penalties, returning a nonsensical value from a function is harmless. But libraries like jQuery actually give meaning to "no return" in some callbacks. They cleverly let that be the most common behavior, and then let return values specify less common behavior. An example of this in jQuery that creates even more aggravating bugs is event handling. Here's a simple example: http://jsfiddle.net/63fUY/ http://jsfiddle.net/63fUY/ . The expectation is that each time you click either button, the total count will increase. But because of the implicit return on line 13, preventDefault gets called half the time. That's an incredibly easy mistake to make, a huge pain to hunt down, and awkward to write a test for. And it would be so easy to avoid if the language had a syntax for "default to no return" which we could just use on all event handlers.
- niggler 14y agoI certainly agree that CoffeeScript has a bad predictability - it is full of surprises. This 100% captures my experience, especially when it comes to interstitial whitespace sensitivity
- icambron 14y agoMe too. I love CoffeeScript, but even after writing tons of it, I occasionally get frustrated by some whitespace/precedence issue.
- niggler 14y agoI wonder if there's a good IDE or linter to pick up on these issues while you code. It would be difficult to farm out to the compiler on every character change, but I suspect something like that is needed
- esailija 14y agoYou can replace function(data) { return doSomething(data); } With doSomething Named functions are just as first-class as anyonymous ones...
- insraq 14y agoWell, this is more of an example of the syntax. The lambda body might be quite complex.
- esailija 14y agoRight. But I have seen actual code do this plenty of times and there was no explanation in the article so I naturally assumed it was just like those cases where basics of functions are not understood.
- mistercow 14y agoWhile in most cases you can do that, they are not exactly equivalent. For example, you might be passing the callback to a function that attaches members to it. But usually you see wrapping done in order to bind methods, like f = function(data) { return obj.doSomething(data);} If you replaced that with f = obj.doSomething; you'd likely have broken code.
- esailija 14y agoA native method for binding methods has existed for a long time and is called just that: f = obj.doSomething.bind(obj); Wrapping functions like in the example is different and is very common among cargo cultists
- mistercow 14y ago>A native method for binding methods has existed for a long time and is called just that: Well, bind is a relatively recent addition. It wasn't added to IE until IE9, and it wasn't added to Safari until March 2012. In any case, I think that f = (data) -> obj.doSomething data is far more readable than f = obj.doSomething.bind obj Edit: it's also worth mentioning that in Chrome and FireFox, at least, the latter version of f is an order of magnitude slower than the former (http://jsperf.com/native-vs-non-native-bind http://jsperf.com/native-vs-non-native-bind) But yes, wrapping functions is usually (but not always) silly.
- account_taken 14y agoCoffeeScript is more readable if you follow Visual Basic paren rules. Visual Basic, at least the one I used way back when, differentiates between functions and subroutines. Functions whose return values are used in an expression must use parentheses. Subroutines and functions used as subroutines omit parentheses. Example, I often see this. In this trivial example the intent is simple. In real code this style is unnecessary cleverness. a b c, d e In VB, since the return value of `b` and `d` are used, parentheses must be added a b(c, d(e))
- harel 14y agoCoffeeScript and co. ensure new developers who adopt those languages never actually be proficient in JavaScript. Its not a good thing. Perhaps its me, but I just don't get why I'd want to write in one language in order to get code in another. Why not just learn the target language? And please don't bring up the "You write C which gets compiled to assembly or Python which ends up as C" etc. Its not the same thing. JavaScript is not Assembly and its not Machine Language. Its a very simple language and its quirks can be learned quite easily. Its not that more verbose than CoffeeScript. Don't get me wrong, I think CoffeeScript's syntax is nice, but its nice in an academic kind of way, not in as a replacement for a language that if you work and develop for the browser, you should know very well and be friends with. Its a dangerous short cut.
- account_taken 14y agoOne cannot be proficient in CoffeeScript without being proficient in JavaScript. How could they debug anything?
- harel 14y agoFirst of all why would you want to end up debugging on one language and writing on another? This is why I specifically mentioned 'new developers'. But I also mean developers who know basic JavaScript and jump on the CoffeeScript hype wagon because its there and its hip.
- kam 14y agoSourceMap.
- hilko 14y agoExactly. I would never advise someone to use CoffeeScript without first knowing JavaScript, but I think very few people would do this anyways. And even if they tried, aside from debugging issues, I think the article shows that it's pretty hard to work with CoffeeScript if you don't understand the underlying output code.
- tlrobinson 14y ago"Perhaps its me, but I just don't get why I'd want to write in one language in order to get code in another. Why not just learn the target language?" I bet someone has uttered nearly these exact words when debating assembly versus C/Fortran/etc.
- PasserBy2 14y ago"...since most people are brainwashed by class-based mechanism" - that is a very constructive language indeed.