This discovery stemmed from the reply in another post, but since it’s less relevant to the initial post, I thought I would make a new post dedicated to it.
julia> box = fill(1)
0-dimensional Array{Int64, 0}:
1
julia> function f1()
function (x)
box[] + 1
end
end
f1 (generic function with 1 method)
julia> function f2(localBox::Array{Int, 0})
function (x)
localBox[] + 1
end
end
f2 (generic function with 1 method)
julia> f1c = f1()
#1 (generic function with 1 method)
julia> f2c = f2(box)
#3 (generic function with 1 method)
julia> box[] += 1
2
julia> f1c(1)
3
julia> f2c(1)
3
julia> f1c_dc = deepcopy(f1c)
#1 (generic function with 1 method)
julia> f2c_dc = deepcopy(f2c)
#3 (generic function with 1 method)
julia> box[] += 1
3
julia> f2c_dc(1)
3
julia> f1c_dc(1)
4
julia> check_type(::F) where {F} = (isbitstype(F), Base.issingletontype(F))
check_type (generic function with 1 method)
julia> check_type(f2c)
(false, false)
julia> check_type(f1c)
(true, true)
Why didn’t deepcopy sever the reference to the global variable box for f1c_dc? And why is f1c considered an instance of bitstype and singletontype even though it technically references the “same” global variable box as f2c? I understand that for f2c, the box was never directly used to construct its body, but through a local variable localBox that points to box. However, the result remains effectively the same for f1c and f2c, as they both reference the same data stored in box.
Consider the case where an object is not a closure but a Tuple:
julia> v1 = (box,)
(fill(3),)
julia> v2 = deepcopy(v1)
(fill(3),)
julia> box[] = 5
5
julia> v1
(fill(5),)
julia> v2
(fill(3),)
Even though v1 is constructed by directly using box, applying deepcopy on v1 sever its internal data’s connection to box (see v2). Why does deepcopy not affect f1c the same way it affects f2c?