Ahhh, the closure explanation makes sense Mauro. I have used closures 
before but my shared state variables were always arrays which were mutated 
inplace so the closure scoping behavior acted just like the global scoping 
rules. For example, my closures always looked like this:

julia> function makeclosure{T<:Real,d}(state::Array{T,d})
           function updatestate()
               state[:] .+= 1
           end
           function printstate()
               println(state)
           end
           return updatestate::Function, printstate::Function
       end
makeclosure (generic function with 1 method)

julia> u1, p1 = makeclosure(rand(2,2))
(updatestate,printstate)

julia> p1
printstate (generic function with 1 method)

julia> p1()
[0.3377313966339588 0.2705755846071063
 0.4035312377015656 0.7008059914967171]

julia> u1()
4-element Array{Float64,1}:
 1.33773
 1.40353
 1.27058
 1.70081

julia> p1()
[1.3377313966339588 1.2705755846071063
 1.4035312377015656 1.700805991496717]

I can now see that people would want similar behavior for non-arrays and 
non-mutating operations on the local state. In particular, the following 
closure works like the above closure but for Numbers.

julia> function makeclosure{T<:Number}(state::T)
           function updatestate()
               state += 1
           end
           function printstate()
               println(state)
           end
           return updatestate::Function, printstate::Function
       end
makeclosure (generic function with 2 methods)

julia> u2, p2 = makeclosure(1)
(updatestate,printstate)

julia> p2()
1

julia> u2()
2

julia> p2()
2

Of course, now the scoping behavior within makeclosure conflicts with the 
global REPL behavior.

I took a look at your updated version of that section in the manual. I like 
the new example on closures. I have two comments. First, you might want to 
extend the closure example beyond the let block. Mainly because it wasn’t 
immediately obvious to me how that let block closure was useful. Second, 
I’m starting to think that the manual could use a subsection titled 
“Scoping rules for nested functions” which makes clear that functions 
within functions have different behavior than functions defined in a module 
or the REPL.

Thanks for your help Mauro!

BTW: Mauro, feel free to copy, cut, paste and mutate any of the above text 
if you think it would be useful for your draft of that section of the 
Manual.

On Thursday, July 16, 2015 at 6:01:36 AM UTC-7, Mauro wrote:

> Question 2) What advantage is there for changing the scoping rules for 
> > nested functions? 
>
> How is this for an explanation: 
>
> https://github.com/mauro3/julia/blob/m3/scope-doc/doc/manual/variables-and-scoping.rst#hard-vs-soft-local-scope
>  
>
​

Reply via email to