Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
inner scopes don't shadow variables; large potential for bugs #238
There is a slight conflict when there is no explicit variable introduction and variables are mutable (in any language). You might accidently re-use a more outer variable in a inner function, while you wanted to shadow it instead.
This example is trivial; but in the real world this happens easily with only local meaningful variables like an
The trouble is:
But there are two distict uses: (1) you need a new (local) variable; (2) you want to assign a new value to a (more) global variable. Trouble is with (1): you need to keep in your head a list of all more global variables.
I'm willing to bet this will cause someone to waste a day of debugging, which turns out to be a unexpected sharing of a more outer variable.
It's certainly possible to accidentally blow away an outer variable within an inner scope, but (in Ruby and Python), this turns out not to be a very common problem. If you don't nest functions too deeply, don't introduce a lot of globals, and give things proper names, it never arises.
So, I'd like to make the argument that having named variables observe consistent lexical scope -- you can be sure that you're dealing with the same variable in inner functions, and not something unrelated, is a more pleasant experience. Allowing
no and no. ruby has:
Ruby advantage is that you don't need that many local variables; due to class and instance variables.
python is even different:
Which is weird, but then python doesn't have lexical scoping at all. So don't look at python.
I disagree. Doing it once is quite natural, fresh variable? use
(As appossed to the coffee-script flowchart: fresh variable? ensure your name is unique in all enclosing scopes.)
Your final argument is a matter of taste. But inside inner scopes, the more-local variables are, the more relevant to the code they are. I would argue it is easier to keep track of the more-local variables, as apposed to all the more-global variables. And any meaningful global variables you would give meaning full names.
So how do I know not to use 'old' as tmp variable name?
However; it looks much better (much more declarative) if you don't have to write
grayrest -- To create globals in CoffeeScript on purpose, simply attach your variable to the global object (
As for Ruby's variable options --
Yes, you need to ensure that your name is unique to the enclosing scope, but you should be doing that in any case. Scopes should be short and sweet, and not nested deeply. CoffeeScript is making it easier to write well structured code (by omitting
The way Coffee scopes variables now is working out just great. I have not had any issues with it so far. Being able to access outer variables from inner scopes is useful at times:
In this case, if Coffee defines a local variable to
Its not global variables that are the problem; its the local variable that is accidentally used in an outer scope too, creating havoc.
As said, the way it currently works is a choice, and it is not even a bad choice per-se. It would not be my choice, but that is besides the point. But it is a choice that you would want to explicitly document as a potential pitfall.
Probably; unfortunately any trivial example will resort to bad-style/good-style debate. Which is not the debate at all. Quite sure there can be code that must be considered very good style, but still runs into this accidental variable sharing problem.
Also for completeness; indeed that would create a true global. But for static scopes, any variable defined in a more outer scope is 'global' (also called free). What we used to call global variables come from languages that cannot do closures (like c or java). But talking about those does not really contribute to the issue at hand.
Nothing would change in how your example works.
That is the problem, what if you think you are using a different variable, but you accidentally did not and change state somewhere where you didn't intend to do so?
If you want a new variable; you can mark that using
(And if coffee-script would add this, any coffee-script-lint would immediately warn on any variable introduction that skips the