Puzzled by scope rules

When running

function ten()
    j = 1
    while j < 10
        global j += 1
    end
end
println(ten())

one gets

ERROR: LoadError: UndefVarError: j not defined

Which would be the correct way to define j? The block inside the function runs fine. Thanks in advance.

There is no global j defined, e.g. this would solve the error, but result in an infinit loop:

j=1
function ten()
    j = 1
    while j < 10
        global j += 1
    end
end
println(ten())

You can translate it into:

global_j=1
function ten()
    local_j = 1
    while local_j < 10
        global global_j += 1
    end
end
println(ten())

Where you see why it never stops.

2 Likes

Thank you for your reply. This works

function ten()
    global j = 1
    while j < 10
        global j += 1
    end
    return j
end
println(ten())

but is not very pretty!

Of course it’s not pretty, and why do you use global in your code above? It would work just without global.

2 Likes

I think @oheil is explaining how you could use globals in this code. But you shouldn’t use globals here at all. Do this instead:

function ten()
    j = 1
    while j < 10
        j += 1  # no global!
    end
end
println(ten())
5 Likes

Thank you. I am learning Julia reading the manual. It all started in the section about Loops where is given the following example:

julia> i = 1;
julia> while i <= 5
           println(i)
           global i += 1
       end

I decided to see what would happen if this code block was inside a function…

Actually I didn’t explained why the error comes up. See:

function ten()
    j = 1
    while j < 10
        global j += 1
    end
end
println(ten())

I translate it again:

function ten()
    local_j = 1
    while local_j < 10
        global global_j
        global_j = global_j + 1
    end
end
println(ten())

The undefined j is the bold one in: global_j = global_j + 1

I think it is great that you are reading the manual, many questions we answer here are asked because people do not make this investment. In your case, the answer is in the next section Scope of variables. Unfortunately we have kinda of a deadlock here: we want the manual teach to control flow before scope, so we can use for loops in the scope section; however, because we did not explain scope first, all examples in the Control Flow section use global variables direct in the REPL (and do not exactly explain why).

@Tamas_Papp You were doing a manual rewrite. Do you think this is something to consider? (Changing the order of the sections or making some adaptation.) I find kinda worrying that newbies are taught how to use global variables inside a loop before understanding how scope works. Maybe I could give a look at it this weekend.

5 Likes

Generally improvements to the manual are always very welcome, but I am not sure that a strictly linear reading order (like a novel) is feasible; a lot of things are interconnected. IMO the manual is best read multiple times.

5 Likes

I have some notes that may help understanding how these scope rules work: Scope of loops · JuliaNotes.jl

They of course do not bring nothing new that the manual does not cover.

1 Like