How to correctly define and use global variables in the module in Julia?

I also say that you do not need explicit global declaration here at all. (See below.)

A. The global and the two ::Float64’s below are redundant:

module A
global a = 100.0::Float64
function f(x)::Float64
    a = x^2
    return a
end
println("f(6.0) = ", f(6.0), ",  a = ", a)
end;
f(6.0) = 36.0,  a = 100.0

B. The A above is equivalent to the following:

module B
a = 100.0
function f(x)::Float64
    a = x^2
    return a
end
println("f(6.0) = ", f(6.0), ",  a = ", a)
end;
f(6.0) = 36.0,  a = 100.0

B′. Don’t write return-type in general (cf. return-type). B′ is better than B and B is better than A.

module B′
a = 100.0
function f(x)
    a = x^2
    return a
end
println("f(6.0) = ", f(6.0), ",  a = ", a)
end;
f(6.0) = 36.0,  a = 100.0

C. We need global for the immutable global variable a in function.

module C
a = 100.0
function f(x)
    global a = x^2
    return a
end
println("f(6.0) = ", f(6.0), ",  a = ", a)
end;
f(6.0) = 36.0,  a = 36.0

D. We don’t need global for the content a[] of the mutable global variable a:

module D
a = Ref(100.0)
function f(x)
    a[] = x^2
    return a[]
end
println("f(6.0) = ", f(6.0), ",  a[] = ", a[])
end;
f(6.0) = 36.0,  a[] = 36.0

E. The D above is type-unstable. We need const for type stability:

module E
const a = Ref(100.0)
function f(x)
    a[] = x^2
    return a[]
end
println("f(6.0) = ", f(6.0), ",  a[] = ", a[])
end;
f(6.0) = 36.0,  a[] = 36.0

For type (un-)stability, please compare the results of @code_warntype D.f(6.0) and @code_warntype E.f(6.0).

Postscript: A code will be more readable and efficient if the global variables that store the parameters of a problem are passed as arguments to functions everytime. See Problem-Algorithm-Solver pattern.

4 Likes