Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using variable inside a for eachrow loop causes error

Tags:

julia

I am trying to understand why using variable i inside the loop causes an issue

File main2.jl:

struct MyStruct
    a::Int32
    b::Int32
    c::String
end

df = DataFrame( A=Int[], B=Int[] )
push!(df, [1, 10])
push!(df, [2, 20])
push!(df, [3, 30])

insertcols!(df, 3, :C => MyStruct.(Int32(0), Int32(0), ""))
insertcols!(df, 3, :D => Vector{MyStruct})

println(df)

i = 1
for r in eachrow(df)
    i = i + 1
end

I get:

julia> include("main2.jl")
|     A |     B |                 D |                    C |
| Int64 | Int64 |          DataType |             MyStruct |
|-------|-------|-------------------|----------------------|
|     1 |    10 | Array{MyStruct,1} | MyStruct(0, 0, \"\") |
|     2 |    20 | Array{MyStruct,1} | MyStruct(0, 0, \"\") |
|     3 |    30 | Array{MyStruct,1} | MyStruct(0, 0, \"\") |
ERROR: LoadError: UndefVarError: i not defined
Stacktrace:
 [1] top-level scope at /usr/home/.../main2.jl:19
 [2] include at ./boot.jl:328 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1094
 [4] include(::Module, ::String) at ./Base.jl:31
 [5] include(::String) at ./client.jl:431
 [6] top-level scope at REPL[3]:1
in expression starting at /usr/home/.../main2.jl:18

julia> 
like image 817
M.E. Avatar asked Dec 15 '25 05:12

M.E.


1 Answers

The problem is that i lives in the global scope and when you write a for loop in the global scope, it creates it's own sub-scope. You can solve the issue by changing your for loop to

i = 1
for r in eachrow(df)
    global i
    i = i + 1
end

However, inside function bodies, you do not need to do this (as long as i lives in the function body).

This comes down to the fact that in Julia, you often shouldnt be writing non-trivial code out in the global scope. It's considered to be proper form to put code inside functions. If the code isn't inside a function, it won't be compiled and you won't get any of the performance benefits of using Julia. More info about scoping rules can be found here: https://docs.julialang.org/en/v1/manual/variables-and-scoping/

There has been a lot of discussion over this issue and what people would rather happens instead. The discussion more or less started here: https://github.com/JuliaLang/julia/issues/28789 and then a solution was proposed here: https://discourse.julialang.org/t/another-possible-solution-to-the-global-scope-debacle/ and then now a new potential solution was discussed here: https://discourse.julialang.org/t/new-scope-solution/16707 .

It looks like currently there is no real consensus on how to change the bahaviour and so it will likely stay as is. For what it's worth, I prefer the current behaviour and think it has some advantages, though it is often surprising to newcomers.

like image 184
Mason Avatar answered Dec 16 '25 23:12

Mason



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!