Well, itâs not exactly about const or mutable/immutables, itâs about scopes. Process of assignment value to a variable is called binding, and since there can be multiple scopes, there are some rules how binding process should occur.
In your example, when you are writing a = x^2
you are in so called hard-scope
(scope of the body function). By the scoping rule, existence of global variable with the same name is ignored and new variable is created (inside function scope) and it is assigned a new value, this way, it shadows global variable. You can override this rule with the keyword global
, i.e. the following is working as you intent
a = 100.0
function f(x)
global a = x^2
return a
end
println("f=",f(6.0)," a=",a)
# f=36.0 a=36.0
I do not know Fortran, so I can be wrong, but by judging how you are using word global
, it is possible, that in Fortran global
variable means âwhenever you meat assignment to this variable (in any scope) always use global variableâ and you set this rule once and for all. If I am correct, then it is different from Julia, where global
means in this particular scope if you see word "global" then use global variable instead of local
. This is why your initial example have redundant global
in global a = 100.0
because there is no ambiguity in this case (a
is already global in this scope), so it is just ignored by compiler.
Another important thing is relation between mutable and immutable constructs. You can say that these scope rules contradicts to this example
a = [100.0]
function f(x)
a[1] = x^2
return a
end
println("f = ", f(6.0), " a = ", a)
f = [36.0] a = [36.0]
and it looks as if scoping rule is ignored if a
is vector (or Ref
, it is the same for this discussion).
Well, the thing is, a[1] = x^2
is a lie :-). It may look like an assignment, but it is not. In reality it is just a syntax sugar for special function setindex!
, so previous code in reality is the following
a = [100.0]
function f(x)
setindex!(a, 1, x^2)
return a
end
As you can see, in this representation, there is no rebinding of the variable a
. Itâs binding hasnât changed (in C-like terms you can say that it is still the pointer to the same memory region, it is contents of this region has changed). And since a
binding hasnât changed, in this example there is no ambiguity and global variable is used and updated.
If itâs clear, than you should have no problems to understand why following code returns what it returns
a = [100.0]
function f(x)
a = [2.0]
a[1] = x^2
return a
end
println("f = ", f(6.0), " a = ", a)
and compare it to
a = [100.0]
function f(x)
global a = [2.0]
a[1] = x^2
return a
end
println("f = ", f(6.0), " a = ", a)