x=1
y=2
z=3
u=4
a=5
v=6
let x=11, y=11, z::Int=11, u::Int=11, v=(a=11; 22)
x=22
println("x = ", x)
println("y = ", y)
println("z = ", z)
println("u = ", u)
println("a = ", a)
println("v = ", v)
println(x+y+z+u+v+a)
end
x=11
println("x = ", x)
println("y = ", y)
println("z = ", z)
println("u = ", u)
println("a = ", a)
println("v = ", v)
println(x+y+z+u+a+v)
I would expect a to be 11, after the let but when I run it , it says it is 5. Here is the output. Is this expected?
julia> x=1
1
julia> y=2
2
julia> z=3
3
julia> u=4
4
julia> a=5
5
julia> v=6
6
julia> let x=11, y=11, z::Int=11, u::Int=11, v=(a=11; 22)
x=22
println("x = ", x)
println("y = ", y)
println("z = ", z)
println("u = ", u)
println("a = ", a)
println("v = ", v)
println(x+y+z+u+v+a)
end
x = 22
y = 11
z = 11
u = 11
a = 11
v = 22
88
julia> x=11
11
julia> println("x = ", x)
x = 11
julia> println("y = ", y)
y = 2
julia> println("z = ", z)
z = 3
julia> println("u = ", u)
u = 4
julia> println("a = ", a)
a = 5
julia> println("v = ", v)
v = 6
julia> println(x+y+z+u+a+v)
31
1 Like
Yes, the assignment happens within a let
block so outside it is unaffected. See
https://docs.julialang.org/en/v1/manual/variables-and-scoping/
1 Like
oheil
July 27, 2020, 7:59am
3
I thought about this too, and hesitated to answer after I tried the following:
julia> function test()
a=5
v=5
println("a=",a," v=",v)
let v=(a=11;22)
println("a=",a," v=",v)
end
println("a=",a," v=",v)
end
test (generic function with 1 method)
julia> test()
a=5 v=5
a=11 v=22
a=11 v=5
Is there a difference between let
in the REPL and let
inside a function? Apparently, but is there something written about this difference? Didnβt found something detailed.
This is my mental model of how let
works:
let v = (a = 11, 22)
end
can be written as by expanding the (;)
as
let
a = 11
tmp1 = 22
let v = tmp1
end
end
Then within a function, a = 11
updates the outer local scope, while within the global scope the a
inside let
is global.
If updating in the latter case is desired,
v, a = 5, 5
let v = (global a = 11; 22)
end
v, a # 5, 11
1 Like
rdeits
July 27, 2020, 3:16pm
5
I think the subtlety here is that:
let x = ...
behaves differently than
let
x = ...
For example:
julia> let
x = 1
let x = 2
x = 3
end
@show x
end
x = 1
1
julia> let
x = 1
let
x = 2
x = 3
end
@show x
end
x = 3
3
The same issue is discussed in Variable declarations within let blocks
I actually donβt think the manual is very clear on this topic: Scope of Variables Β· The Julia Language
In particular, it says
An assignment modifies an existing value location, and let
creates new locations. This difference is usually not important, and is only detectable in the case of variables that outlive their scope via closures.
I think something like the answer from Variable declarations within let blocks would be a good addition to that section of the manual.
4 Likes
oheil
July 27, 2020, 4:00pm
6
So
let v=(a=11;22)
...
end
is equivalent to
let v=22
a=11
...
end
?
If yes, all is clear.
Actually I can check myself:
julia> function test()
a=5
v=5
let v=(a=11;22)
end
(a,v)
end
test (generic function with 1 method)
julia> function test2()
a=5
v=5
let v=22
a=11
end
(a,v)
end
test2 (generic function with 1 method)
julia> @code_lowered test()
CodeInfo(
1 β a = 5
β v@_3 = 5
β a = 11
β v@_4 = 22
β %5 = Core.tuple(a, v@_3)
βββ return %5
)
julia> @code_lowered test2()
CodeInfo(
1 β a = 5
β v@_3 = 5
β v@_4 = 22
β a = 11
β %5 = Core.tuple(a, v@_3)
βββ return %5
)
Answer is yes
1 Like
Please consider making a PR to the docs.