I agree that in your example, it seems obvious that a for
-loop should access that global k
because it would otherwise cause an UndefVarError
. The thing is, letting local scopes automatically reassign existing global variables (like how they reassign outer local variables) would cause difficult bugs. This is a bigger problem for methods, which can run repeatedly, but Iâll show a for
-loop example:
digit = "thumb"
get_finger() = digit
# get_finger() would return "thumb"
k=0
for i=0:9
global k # invisible if automatic
global digit # invisible if automatic
digit = rand(0:9) # random digit from 0 to 9
k = k + digit * 10^i # k gets new leftmost digit
end
# get_finger() would be some random integer now
The clear intention is that get_finger()
accesses a global digit
describing a finger. However, the for-loop assigns a digit
describing an integer from 0 to 9, clearly intended to be a local variable completely separate from the global digit
(note that in your proposal, the global
statements would be invisible).
Well, as you might point out, you have to fix name collisions in local scopes anyway e.g. rewriting as digit_finger
vs digit_number
. Itâs not hard to look over a scope and figure it out, whatâs the difference?
The difference is that any local scope has to be written in its entirety within a file, but a global scope can be written across multiple files and combined into one via include
. The get_finger
code and k
code were substitutes for more complicated code that would be written in separate files:
include("finger.jl")
include("numbers.jl")
include("somethingelse.jl")
include("evenmorestuff.jl")
Now maybe you wrote all of these files separately, and they run just fine on their own, but the moment you tried to combine them into the same global scope, something like get_finger()
is broken. Where is the source of the bug? Itâs not in the file with all the include
s. Maybe itâs in numbers.jl
, maybe itâs somethingelse.jl
, or maybe both. You have to fix a name collision among ALL the files so that a local variable wonât be mistakenly treated as a global one.
Assuming that globals are reassigned automatically as you propose, a way to prevent this problem would be to declare every local variable local
, just to avoid colliding with some global variable in some other file. But there are way more local variables than global variables, so that would be an even bigger hassle.
Aside: you canât reassign variables imported from other modules/global scopes for this reason, too. Easy to break things, hard to figure out where. At least when you add methods to an imported function, you can pin a method to its source module and file.