Because j never gets defined when i = 2 and it doesn’t exist outside of the loop either. The first time the loop runs j is created inside of the loop, but not in the global environment.
This works as expected
for i in 1:2
if i == 1
global j = 1
end
println("i = ", i)
println("j = ", j)
end
i = 1
j = 1
i = 2
j = 1
Ok, lets be more specific, because this behaviour seems very strange to me. I want to define some vectors in the first iteration of my loop, because there is were I find out the size they must have. A minimal example would be:
for i in 1:2
if i == 1
n = 2 # Actually this is reading problem data.
x = zeros(n)
end
println("i = ", i)
println("x[1] = ", x[1])
end
declaring x as global does not seem reasonable to me, and this loop is thought to be inside a function, I do not want x to be a global variable at all.
In fortran this would be something like:
double precision, allocatable :: x(:)
do i = 1, 2
if i == 1 then
n = 2
allocate(x(2))
end if
write(*,*) i, x(1)
end do
That the definition does not work with a a scalar is disturbing to me, really:
do i = 1, 2
if i == 1 then
j = 2
end if
write(*,*) i, j
end do
That this code results in an error is very, very disturbing to me.
Exactly, I need to define x at the start of the function.
That makes things completely equivalent to Fortran, in which I need to declare the variables.
For a vector, I think I could use x = Vector{} instead of allocatable(x), but for a scalar it seems I have to define its value:
julia> function test()
j = 0
x = Vector{}
for i in 1:2
if i == 1
j = 1
x = zeros(3)
end
println("i = ", i)
println("j = ", j)
println("x = ", x)
end
end
end ; test()
This works as expected, although it seems to me that having to define an actual value for the scalar j is not ideal. Also, I am not sure if x = Vector{} is the best way to go there.
Wrapping the code inside a function (which I always do because of the scoping rules of the repl), the two following solutions seem reasonable:
Assigning a value to the variable outside the loop
function test()
#x = Vector{} (commented to remove this error, pointed out by the next post)
x = 0.
j = 0
for i in 1:2
if i == 1
x = rand(3)
j = 1
end
println("i = ", i)
println("x = ", x, " j = ", j)
end
end
Or declaring a local:
function test()
local x
local j
for i in 1:2
if i == 1
x = rand(3)
j = 1
end
println("i = ", i)
println("x = ", x, " j = ", j)
end
end
Seems that the second option provides more information for the compiler, is that correct?
Thank you, this is a very important corrrection indeed, and allows me to advance quite a bit on the understanding of the language. I am still getting used to the idea that variables can things of any kind.
The not-so-obvious scoping rules you see has been discussed quite a bit over the last year or so. It’s a contentious issue and as far as I am aware, no solution was agreed upon.
I encountered same problem and because of my experience with other programming language which usually take more easy about scope specially in loop case, I was a little angry and also disappointed. Based on document, the reason is more clear for me and I think in some cases like software development, it’s not bad to restrict user, but still somehow it’s a hard decision.
One way to using function and avoiding issue with more localization of code. In original document use an example and use global variable to handle it, which is very dangerous and it’s better to not be used, because of general consequence of global parameter.
Anyway, thanks to discussing this issue, for many hours I was struggling with this issue and this discussion help me a lot