Actually I changed my mind and now think this is intended. From the manual on scopes (emphasis mine):
A new local scope is introduced by most code blocks (see above table for a complete list). If such a block is syntactically nested inside of another local scope, the scope it creates is nested inside of all the local scopes that it appears within, which are all ultimately nested inside of the global scope of the module in which the code is evaluated. **Variables in outer scopes are visible from any scope they contain […] unless there is a local variable with the same name that “shadows” the outer variable of the same name. This is true even if the outer local is declared after (in the sense of textually below) an inner block. When we say that a variable “exists” in a given scope, this means that a variable by that name exists in any of the scopes that the current scope is nested inside of, including the current one.
[…]
Whenx = <value>
occurs in a local scope, Julia applies the following rules to decide what the expression means based on where the assignment expression occurs and whatx
already refers to at that location:
- Existing local: If
x
is already a local variable, then the existing localx
is assigned;- Hard scope: If
x
is not already a local variable and assignment occurs inside of any hard scope construct (i.e. within alet
block, function or macro body, comprehension, or generator), a new local namedx
is created in the scope of the assignment;
I don’t like all consequences of this (like the example in this thread) but this is the way it is…
Edit: So the correct way to write snippets above is with using local
inside the inner function: