Scope of a begin (and if) block

Consider the following code, which results in 3 being printed:

x = 3
begin
    local x 
    x = 4
end
println(x)

In the documentation about Scope of Variables it says “the begin construct does not introduce a new scope”, and removing the local x line in the above code makes it behave exactly according to this. However, the begin block seems to introduce some kind of “invisible scope” that is turned into a kind of local scope if the local keyword is used.
Further investigating this:

begin
    x = 3
    begin
        local x
        x = 4    # modifies x from outer begin-block
        y = -1   # global variable y
    end
    println(x)
end
println(y)

leads to 4 and -1 being printed, so the scope introduced seems to default to the outer-most begin, and only apply to variables explicitly declared as local. Would it be correct to conclude begin (and similarly if) introduces a kind of “fall-through” scope (rather than no scope) that is ignored unless explicitly used?

I have a hard time understanding this behavior rigorously and can’t find any answers to this (arguably not very important question) online. Thanks in advance for any ideas about this!

For reference: I am using Julia 1.0 and refer to the corresponding documentation, but I suspect this to be similar in previous versions.

3 Likes

I think this is a bug and should be reported. When writing macros, it is quite common to wrap things in begin ... end blocks or flatten such blocks away. And at least my assumption was that this would always lead to equivalent code.

1 Like

X-ref: https://github.com/JuliaLang/julia/issues/10472