Globals / Constants Act Differently Depending on Use?

I’ve been doing a lot of reading on Constants and Globals, and I realize I really don’t understand what I am reading. Having said that, can you all help me understand why var1 is undefined in the function? It seems to be because I update the value of the Global constant in the function?

Function:

function test()
     println(@isdefined var1)
     println(@isdefined var2)
     if var1
          var1 = false
     elseif !var1
          var1 = true
     end
end

Calling code:

using Revise
includet("test.jl")

global var1 = var2 = true

test()

Output:

julia> test()
false
true
ERROR: UndefVarError: var1 not defined
Stacktrace:
 [1] test()
   @ Main c:\Users\dkzwa\Desktop\figs\test.jl:4
 [2] top-level scope
   @ REPL[5]:1

Is this the only way to overcome this obstacle? It works, but I don’t understand what is going on here:

After further digging, I find that adding one global to var1 in the function makes the function see all var1 in the function as the global var1. The following function works.

function test()
     println(@isdefined var1)
     println(@isdefined var2)
     if var1
          global var1 = false
     elseif !var1
          var1 = true
     end 
end

With the output alternating between:

julia> test()
true
true
false

and

julia> test()
true
true
true

A function defines a hard local scope. This is detailed in the manual Scope of Variables · The Julia Language

In particular, the following passage describes how assigned variables are handled:

When x = occurs in a local scope, Julia applies the following rules to decide what the expression means based on where the assignment expression occurs and what x already refers to at that location:

Existing local: If x is already a local variable, then the existing local x is assigned;
Hard scope: If x is not already a local variable and assignment occurs inside of any hard scope construct (i.e. within a let block, function or macro body, comprehension, or generator), a new local named x is created in the scope of the assignment;

That means the global variable var1 is shadowed by the local one you assign in the function.
To circumvent this, variables can be annotated with global inside a function as you did subsequently.

1 Like

Your test function only has a single local scope and in a single scope a variable can only have one meaning. By writing global var1 you are saying “In this scope, var1 means the global variable var1.” You can have a different var1 that shadow that if you introduce a new inner scope.

1 Like