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
?