Possible compiler bug with shadowed global variable

global z = 12
begin
print(z)
local z = 10
end

this gives an undefined variable error.

this type of backwards-reaching compile error is extremly unusual, and there could be hundreds of lines of code between the the derefrence and the local.

You are not creating a local scope here. If you do use a local scope by using let instead of begin then you get an UndefVarError.

julia> global z = 10
       let
           println(z)
           local z = 12
       end
ERROR: UndefVarError: `z` not defined
Stacktrace:
 [1] top-level scope

The issue I see is that local does not cause an error whem at the top-level.

Edit: Actually, there is some unexpected behavior here I did not expect.

julia> global z = 10
       begin
           local z = 12
           println(z)
       end
       println(z)
12
10

https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Global-Scope

If a top-level expression contains a variable declaration with keyword local, then that variable is not accessible outside that expression. The variable inside the expression does not affect global variables of the same name.

Full discussion in issue 10472, but long story short, declaring local variables in a globally scoped top-level expression is useful for pasting code from functions into the REPL and for macros making temporary variables but keeping the input code in its original scope without knowing if it’s local or global. Apparently a breaking macro hygiene change could get around this oddity, but it’d just complicate things. If it weren’t for making macros work on the global scope, I’d never do this, I’d rather declare select global variables in a local scope where variables are local by default.

local and global declarations occur across the entire enclosing expression no matter where you put them, so they don’t let you swap variable scope line by line. print(z) errored because you didn’t assign local z a value by that point.

This declaration is unnecessary if the pasted code is already in the global scope. Aside, post code between triple backticks ``` lines of code ``` to for monospaced code formatting.

1 Like