On Wed, 2015-03-11 at 10:24, Wendell Zheng <
zhengw...@gmail.com> wrote:
> I did more experiments.
>
> *Input 1:*
> y = 0
> begin
> y = 10
> end
> y
> *Output 1:*
> 10
>
> *Input 2:*
> y = 0
> begin
> local y = 10
> end
> y
> *Output 2:*
> 0
>
> It's the same for *if *block.
begin-end and if-end blocks do not introduce a new scope:
http://docs.julialang.org/en/latest/manual/variables-and-scoping/
So above is the same as not having any blocks. But the behaviour of
local at the REPL is strange:
julia> local y = 10
10
julia> y
ERROR: y not defined
So, what is y local to then? Shouldn't the first line either throw an
error or be equivalent to `y = 10`?
> May I conclude that:
> 1) *Function *introduces *hard scope, *where the assignment introduce new
> local variables;
> 2) Other blocks (including *if*, *begin-end*) introduce soft scope, where
> the assignment either refers to an outer variable
> or introduces an variable which can be conveyed into an outer scope;
> 3) The keyword *global *used in a hard scope turns the hard scope soft;
> 4) The keyword *local *used in a soft scope turns the soft scope hard.
Rule 2 is not right:
julia> for i=1:10
j = 10
end
julia> j
ERROR: j not defined
julia> j = 1
1
julia> for i=1:10
j = 10
end
julia> j
10
So, I think, the rules are these:
In a soft scope:
s1) normal assignment `x = 5`
1) if a binding exists in the global scope, assign to that
2) if no binding exists, make a new *local* binding
s2) local assignment `local x=5`
1) make a new local binding
s3) global assignment `global x=5`
1) make a new global binding
In a hard scope
h1) normal assignment `x = 5`
1) make a new *local* binding
h2) local assignment `local x=5`
2) make a new local binding (i.e. equivalent to h1.1)
h3) global assignment `global x=5`
3) make a new global binding
If no assignment happens, just reading, then hard and soft are equivalent.
The confusing bit about soft scopes are that its rules are dependent on
the outer scopes. I guess the reason for these more complicated rules
are typical usage of loops: being able to modify outside bindings but
newly introduced bindings will go out of scope once the loop terminates.
Another caveat is that these rule seem to break down in nested
functions. Here an example from
https://github.com/JuliaLang/julia/issues/423#issuecomment-4100869
function namespace()
x = 0
function f()
x = 10
end
f()
println(x)
end
namespace() # prints 10, which suggests that the inner function has a soft scope!!!
> By the way, I find the describe of Python's scope in Wikipedia
> <
http://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_vs._dynamic_scoping>
> is quite clear, Could you write the same thing about Julia in Wikipedia?
Well, this is about lexical vs dynamic scope, which is (I think) a
different issue to soft and hard scope.
I'll move some of this discussion to
https://github.com/JuliaLang/julia/issues/9955