

Don't use CoffeeScript - L8D
http://tysens.us/2013/09/06/no-coffeescript/

======
amasad
This is actually almost completely wrong information. The lower-level for loop
is much more JS engine friendly than the Array methods (filter, map etc.). So
unless you write JS like it's C, for the most part, CoffeeScript will probably
generate more efficient code[1]. As shown in the jsperf by @mischani [2]

The only thing that's true is that CofeeScript generates some throwaway code
because of implicit returns and the "everything is an expression" rule.
However, I doubt that they would cause much overhead, specially with modern JS
engines optimisation capabilities.

[1]: [http://mrale.ph/blog/2011/11/05/the-trap-of-the-
performance-...](http://mrale.ph/blog/2011/11/05/the-trap-of-the-performance-
sweet-spot.html)

[2]: [http://jsperf.com/don-t-use-coffeescript](http://jsperf.com/don-t-use-
coffeescript)

~~~
L8D
See my other comment. I too think that using .map, .filter, and .forEach are a
bad idea. But also, if you see the code I would have written in the jsperf,
I'd guess you say that I write JS like it's C.

So, good point.

------
mischanix
Turns out the comprehension is faster on my setup:

[http://jsperf.com/don-t-use-coffeescript](http://jsperf.com/don-t-use-
coffeescript)

~~~
city41
Function calls in JavaScript runtimes (including V8) are quite slow.
Array.map/filter/forEach will always be slower than a for loop doing the same
thing.

I write a lot of games and game related things in JavaScript, and this is
actually a major reason why I now use CoffeeScript. Nice clean comprehension
syntax _and_ better performance.

~~~
jwmerrill
Array.map/filter/forEach aren't just slow because of function call overhead.
They have different semantics than the for loop that you'd typically write
(and that Coffeescript generates), because they support things like arrays
with non-incremental keys. See the reference implementation at [1].

[1] [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#compatibility)

------
rzimmerman
There's no evidence presented here that there's any significant (or even
negative) performance impact from the way the CoffeeScript compiles these list
comprehensions. Also, if your performance is constrained by a list
comprehension, there's nothing in CoffeeScript preventing you from using
"Array.filter" instead. By and large CoffeeScript compiles one-to-one with
JavaScript and when it doesn't, the resulting code is at least reasonably
performant.

I do agree that the default return behavior is probably a bad idea. It
probably came from Ruby, and I can see the appeal, but I've often created bugs
by accidentally using the implicit return, then adding something to the end of
a function. It's not really that big of a deal - I just as a policy always use
an explicit return.

------
city41
Also as an aside, CoffeeScript will only bother to populate the results array
if the comprehension is the last thing in the function. If there is anything
else that follows and you never use the result of the comprehension, then it
compiles into a simple for loop. This is because CoffeeScript can't know if
you actually plan to take advantage of its implicit return in this case.

I have found I've been forced to add a dummy `return` at the end of some of my
CS methods because of this. It's one of only a very few complaints I have with
the language.

------
hardwaresofton
Hey quick question, maybe you should use map instead of filter?

[http://www.dotnetspeaks.com/DisplayArticle.aspx?ID=117](http://www.dotnetspeaks.com/DisplayArticle.aspx?ID=117)
(random site with example)

map is the functional equivalent of what you're trying to do there, not
filter.

~~~
jffry
His criticism still stands that the JS implementation of

    
    
      (number * number for number in nums)
    

...is inefficient, and that it could've been translated into much more
efficient JS than it was.

~~~
city41
It's really not inefficient though. Array.map will be much slower in just
about all environments.

~~~
hardwaresofton
[EDIT] - People have followed up, turns out the comprehension is faster.

------
cubicle67
fwiw, I love coffeescript. I write a game a few weeks ago in it, but I've
never shown it to anyone before. Have a look here if you're interested
[http://quietcode.com/vectroid](http://quietcode.com/vectroid)

I've made no attempts at all at performance tuning yet it runs very nicely in
webkit browsers and not too bad in firefox.

~~~
Kerrick
Very nice!

While playing I noticed I was able to go faster than my projectile, and I was
slightly disappointed when I was unable to damage my own ship that way.

~~~
cubicle67
Yes, I was trying to reward the player for flying faster instead of just
sitting on one spot. Projectile speed increases as your speed increases. I
though damaging your own ship would just be cruel :)

You may also notice the view zooms out as your speed increases, so you have a
much wider view

------
rcoh
It seems that what you actually want is for CoffeeScript to have configurable
backends. I agree that it's silly to generate IE6 compatible code when I know
that I'm targeting node. This isn't a reason not to use CoffeeScript -- it's a
reason to improve CoffeeScript.

Furthermore, as others have noted, your post does smack of premature
optimization. Without numbers, most of the claims are all pretty meaningless.
Judging by number of instructions is no longer a valid metric on any platform
on any level of abstraction and hasn't been since the 1980s.

------
smoyer
I like CoffeeScript and will continue to use it where appropriate.

But I do wonder why we're stuck with all the cruft to let ECMAScript be
backwards compatible. Couldn't we just one time introduce a few breaking
changes to clean up the mistakes in the language's design?

And if you're really opposed to that, how about the same strict versus
transitional semantics we use for HTML? I'd be happy to be writing code in a
clean strict subset of JavaScript.

~~~
roryokane
We already have a strict subset of JavaScript, “strict mode” – see
[https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode).
You activate it by putting the code `"use strict";` at the top of a script or
a function.

------
rpwilcox
The great thing about there being so many Javascript transpilers these days is
that you can pick the right language to suit your needs.

Really want / need Google Closure / the latest ECMAScript stuff? ClojureScript
supports these things pretty well.

Really like Ruby (or Python) but find yourself in Javascript land?
Coffeescript is right for you.

There's some interesting buzz around getting Coffescript more Google Closure
compliant, which is probably the better way to go (assuming your targeting
front end JS, not Node).

But yes, there are certainly places where Coffeescript generates a crap-ton of
code, where if you can pinpoint your Javascript runtime (like in Node's case)
you could do more, better, and faster.

------
tlrobinson
This person seems to think that "less code" is "faster code".

 _Yes, I do have to give some credits to putting the number x number directly
into the push call_

Are they really suggesting

    
    
        _results.push(number * number);
    

is significantly faster than, say

    
    
        var result = number * number;
        _results.push(result);
    

Because it's not.

Though I do wonder why CoffeeScript doesn't do something like this to avoid
the function call:

    
    
        _results[_i] = number * number;

------
talles
Yet Another Coffeescript Rant

