# 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