On Wed, 2015-03-11 at 10:24, Wendell Zheng <[email protected]> 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 > On Tuesday, March 10, 2015 at 10:40:53 PM UTC+1, Mauro wrote: >> >> I think this is the soft vs hard scope issue. See: >> https://github.com/JuliaLang/julia/issues/9955 >> >> That issue could use some fleshing out though... >> >> On Tue, 2015-03-10 at 20:03, Wendell Zheng <[email protected] >> <javascript:>> wrote: >> > *Input 1:* >> > y = 0 >> > function foo() >> > y = 10 >> > end >> > foo() >> > y >> > >> > *Output 1:* >> > 0 >> > >> > *Input 2:* >> > y = 0 >> > for i = 1:1 >> > y = 10 >> > end >> > y >> > >> > *Output 2:* >> > 10 >> > >> > In the first example, y introduces a local variable. >> > In the second example, y is still a global variable. >> > >> > This is not consistent to what the official document said. >> > >> > I tried these examples in JuliaBox. >> >>
