Reputation: 709
What is wrong with my code? Do I have to declare x
before using it?
function f(n::Int64, t::Int64)
A = ones(n,n)
for i=0:t
if i > 0
A[x,a] = rand()*A[x,a] + rand()
end
y = rand(1:n)
b = rand(1:n)
if i > 0
A[x,a] = rand()*A[x,a] + rand()*A[y,b]
end
x = y
a = min(b, rand(1:n))
end
return A
end
Here is the error thrown when trying to call f
:
UndefVarError: x not defined
Upvotes: 1
Views: 754
Reputation: 69819
I think that the reason is more complex, as similar code in Python would work.
For example compare (Python):
>>> def f():
... for i in range(3):
... if i > 0:
... print(a)
... a = i
...
>>> f()
0
1
to (Julia):
julia> function f()
for i in 0:2
if i > 0
println(a)
end
a = i
end
end
f (generic function with 1 method)
julia> f()
ERROR: UndefVarError: a not defined
So what is the difference? As the Julia manual explains here you have:
for
loops,while
loops, and comprehensions have the following behavior: any new variables introduced in their body scopes are freshly allocated for each loop iteration, as if the loop body were surrounded by alet
block
This means that in your code variables a
and x
as they are local to the for
loop are freshly allocated in each iteration of the loop. Because of this the variable has to be assigned to before it is accessed inside the loop.
Therefore it is not needed to assign a value to x
and a
before the loop. It is enough to define them in scope outer to the loop (even without assigning of the value). For example like this:
julia> function f(n::Int64, t::Int64)
A = ones(n,n)
local x, a
for i=0:t
if i > 0
A[x,a] = rand()*A[x,a] + rand()
end
y = rand(1:n)
b = rand(1:n)
if i > 0
A[x,a] = rand()*A[x,a] + rand()*A[y,b]
end
x = y
a = min(b, rand(1:n))
end
return A
end
f (generic function with 1 method)
julia> f(1,1)
1×1 Array{Float64,2}:
0.94526289614139
Now it works because x
and a
are not freshly allocated in each iteration of the loop.
In my original toy example it would look like:
julia> function f()
local a
for i in 0:2
if i > 0
println(a)
end
a = i
end
end
f (generic function with 2 methods)
julia> f()
0
1
and you see that you get exactly what you had in Python.
Upvotes: 2