Variable undefined in for loop

Calculating the sum from 1 to 10:

function myfunc(x)

    k = nothing

    for i = 1:10

        println(k) #crashes here

        if isnothing(k)
            global k = i
        else
            global k = k + i
        end
    end
    return k
end

myfunc(1)

Error points to the line with println(k)

ERROR: UndefVarError: k not defined
Stacktrace:
[1] myfunc(x::Int64)
@ Main ~/data/shorttest.jl:8
[2] top-level scope
@ ~/data/shorttest.jl:21

It seems that it works if I remove “global” definition. But in this case a new local variable should be created at

k = i

and the outer scope variable k should remain “nothing”.

Yes, your function will work fine if you remove the global keywords.

global is used when you want to explicitly refer to a global variable from within a function. Consider this code:

foo = 1

function f()
    println(foo)
end

function g()
    foo = 2
    println(foo)
end

function h()
    global foo = 3
    println(foo)
end

The following will happen:

f() # prints 1 because it prints the global `foo`
g() # prints 2 because it prints the local `foo`
h() # prints 3 because it sets the global `foo` to 3 and prints it
f() # prints 3 because it prints the global `foo` which has been set to 3 before

See Scope of Variables · The Julia Language for a detailed explanation.

3 Likes

No. The for loop inherits the outer local scope. Here is a simpler case.

julia> function f()
           k = 1
           for i in 1:10
               k = i
           end
           return k
       end
f (generic function with 1 method)

julia> f()
10

As a side note, the compiler figures out that it does not need to execute the for loop in this case.

julia> @code_llvm f()
;  @ REPL[12]:1 within `f`
define i64 @julia_f_255() #0 {
top:
;  @ REPL[12]:6 within `f`
  ret i64 10
}

If you wanted to create a new local scope for k, you can use let.

julia> function f()
           k = 1
           for i in 1:10
               let k = i
                   sleep(k/100)
               end
           end
           return k
       end
f (generic function with 1 method)

julia> f()
1
1 Like