"for" and "function" don't work in the same way in terms of scope

164 views
Skip to first unread message

Wendell Zheng

unread,
Mar 10, 2015, 5:30:29 PM3/10/15
to julia...@googlegroups.com
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.

Mauro

unread,
Mar 10, 2015, 5:40:53 PM3/10/15
to julia...@googlegroups.com
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 <zhengw...@gmail.com> 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:*

Wendell Zheng

unread,
Mar 11, 2015, 4:49:11 AM3/11/15
to julia...@googlegroups.com
I cite what StefanKarpinski said in issue 423. Is it the ultimate answer?
StefanKarpinski commented on 22 Feb 2012

Here's an idea for how to fix this. The idea is to have "hard scope" and "soft scope". Functions introduce "hard scope" whereas various blocks introduce "soft scope". The difference would that in a new hard scope, assignment without a "global" or (hypothetical) "outer" declaration always creates a new variable local to that scope, regardless of whether a variable with that name exists in the outer scope. In a new soft scope, assignment updates a variable in the outer scope if such a variable exists or creates a new inner-scoped variable if no such variable exists. Some examples of the proposed behavior (not how things work now):

x = 0
while x < 10
  println(x)
  x += 1
end

Works: prints 0 through 9.

x = 0
function step()
  println(x)
  x += 1
end
while x < 10
  step()
end

Fails: complains that x inside of step() is undefined.

Wendell Zheng

unread,
Mar 11, 2015, 5:24:11 AM3/11/15
to julia...@googlegroups.com
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. 

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.

By the way, I find the describe of Python's scope in Wikipedia is quite clear, Could you write the same thing about Julia in Wikipedia?



On Tuesday, March 10, 2015 at 10:40:53 PM UTC+1, Mauro wrote:

Mauro

unread,
Mar 11, 2015, 9:04:03 AM3/11/15
to julia...@googlegroups.com

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

> 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 <zhengw...@gmail.com
Reply all
Reply to author
Forward
0 new messages