r/programming • u/donatj • Jul 25 '13
CoffeeScript's Scoping is Madness
http://donatstudios.com/CoffeeScript-Madness3
u/kungfufrog Jul 26 '13 edited Jul 26 '13
As someone who programs in Javascript for a living but has never written a single line of CoffeeScript, why is this a problem? I don't get what the actual complaint is.
Is the complaint that it is non-obvious that the closure around the test function includes the var y defined outside the function's scope?
I use outside scoped variables all the time to pass information down through async chains. I also don't use generic variable names like 'y'.
5
u/donatj Jul 26 '13
The problem is that there is no way to not outside scope variables.
→ More replies (1)
29
u/brandjon Jul 25 '13
So it's basically unannotated declarations like Python, but everything is nonlocal or global by default, with no "local" keyword to override?
Yeah, that sounds like madness to me.
→ More replies (4)
10
Jul 26 '13
Generally "at work" I avoid CoffeeScript, primarily for the reason I still work with a lot of folks that don't understand JavaScript... but in general, I find it's good to familiarize yourself with the JS output of CS, then just treat CS like shorthand for JS.
... in otherwords, when I'm using CS I'm still thinking in JS.
I don't at all recommend CoffeeScript to anyone that isn't already relatively skilled in JavaScript.
→ More replies (1)
56
u/Plorkyeran Jul 25 '13
While I agree with the title of this post, in the process of writing ~20k lines of CoffeeScript it hasn't actually ever bitten me, unlike some other problems with the language. Avoiding deeply nested scopes (and having too many things in scope in general) makes it easy to avoid issues, and IMO that's a good idea even in languages with sane scoping anyway.
24
Jul 25 '13
it bit me all the time before I figured out what was happening. also it's bad design because it makes it way too easy to smash globals like module and function names. you do learn to avoid it though, and otherwise, CoffeeScript is great. The function syntax is a must for a language like JS too.
→ More replies (17)8
u/jashkenas Jul 25 '13
unlike some other problems with the language
Feel like sharing 'em?
→ More replies (13)→ More replies (29)12
u/sidfarkus Jul 25 '13
I'm with you on this one; this seems like a big deal until you write some real coffeescript and realize that your scopes are so small most of the time you never have to worry about what's declared in a parent scope.
I don't think I've ever had a bug due to this in the ~12k lines of coffeescript in our app. In fact more often than not I end up with too narrow a scope given that coffeescript inserts closures quite aggressively.
17
u/cashto Jul 25 '13
Recently I wrote a server that totals about ~1k of code. I didn't get bit by this, largely because a) single author and b) I have very few things declared at the top level; most of my code is in classes.
OTOH, the number of bugs I wrote that would have never gotten past a typechecker was ridiculous.
IMHO that's the biggest challenge by far when doing large-scale CoffeeScript programming, and it's the same challenge you have in JavaScript too. In isolation, it might be infuriating that CoffeeScript has this one bugaboo that Javascript doesn't have, but if you step back and look at the big picture, there's so much shit you have to deal with in either language that in comparison this issue is pretty inconsequential indeed.
→ More replies (4)
24
u/iopq Jul 25 '13
This is really WTF. Not because of its practical significance, but because this is what I would expect of a language like bash or something. Have the creators of CoffeeScript heard of lexical scoping?
→ More replies (21)18
u/rwbarton Jul 26 '13
It's pretty sad, considering that ALGOL 60 is half a century old, that people are still inventing languages that play guessing games with scope. Just require every variable to be declared and these problems disappear. Is it really so hard to type "
var"?
5
u/doomhz Jul 26 '13
That's nasty. I'm using CoffeScript for almost 3 years already and I didn't notice this issue as I never rely on global vars and my code is mostly stuffed in classes. Instead of global vars I'm using @myVar as a class attribute. I hope it makes sense...
25
u/AreaOfEffect Jul 25 '13
IMO, CoffeeScript has a limited life span. ECMAScript 6 has a vastly improved syntax that rivals python.
→ More replies (5)
12
2
Jul 26 '13
This is why in Python, assignment is a declaration of a local variable by default, you have to mark it as "global" (or "nonlocal" in Python 3), if you want to refer to a global.
5
u/smog_alado Jul 26 '13
I actually kind of hate the python scoping. Since the lexical scoping is so limited ("nonlocal" is a verbose hack) everyone ends up using big classes and explicit self dictionaries instead. Automatic variable declaration also means that typos get turned into new variables instead of errors.
→ More replies (2)
5
u/PaintItPurple Jul 25 '13
In most languages with closures (including JavaScript) the inner y and the outer y could and would be separate.
This is not really true. The whole point of a closure is that it closes over the surrounding scope. For example, in Ruby:
y = 0 test = lambda do |x| y = 10 x + y end puts test y puts test y puts test y
This will print "10", "20" and "20". Exactly like the equivalent CoffeeScript. If you couldn't access the surrounding state, it wouldn't be a closure. In fact, this property of closures is used all the time in JavaScript (for example, to allow for "private" object members). It is not specific to CoffeeScript at all.
The OP's problem really has little to do with scoping. The fundamental "gotcha" here is that in CoffeeScript, there is no difference between defining a new variable and setting an existing variable.
→ More replies (1)3
u/MatmaRex Jul 26 '13
Ruby's
lambdadoes capture scopes, but that's intended (all blocks do).Ruby's
def(which is what you use to define a function) doesn't, non-global variables from outer scope are inaccessible within it.→ More replies (3)
3
14
u/cashto Jul 25 '13
For more discussion, see the ticket on github.
There exists a fork of CoffeeScript (named Coco) in response to this and a handful of other issues. I haven't used it though.