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
>
>