I am learning Julia using Ivo Balbaert\'s book. He uses the following example:
anon = Array{Any}(undef, 2)
for i = 1:2
anon[i] = () -> println(i)
i +
This is pretty tricky. You need to know two things:
for
loop variable i
gets a fresh binding on every iteration (I guess you know it - I do not know Ivo's book, but from your question I guess this is what he is discussing in it)Now to explain the second point have a look at the following (I assume you have run the code above):
julia> anon[1].i
Core.Box(2)
julia> anon[1].i.contents
2
And you can see that anon[1]
has boxed the binding to i
that was present in the first iteration of the loop. As in the second loop the binding to i
is fresh anon[2]
has a reference to this fresh binding.
You can even access this memory location like this:
julia> anon[1].i.contents = 100
100
julia> anon[1]()
100
or even like this (not recommended):
julia> for i = 1:2
anon[i] = () -> println(i)
anon[i].i.contents = 100 + i
i += 1
println(i)
end
102
103
julia> anon[1]()
102
julia> anon[2]()
103
Finally note that within a single iteration of the loop assigning to variable i
does not change the binding (you are writing to the same memory location).