Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set Empty DefaultDict to new struct object may leads to pass by copy #793

Open
dmoliveira opened this issue Mar 20, 2022 · 1 comment
Open

Comments

@dmoliveira
Copy link

Based on my tests using the DataStructures package, if you create a new DefaultDict empty and pass it to your new object it does not pass by reference but by copy and this leads to strange behaviour (imho). This is very subtle for me and should give some error or warning when you try.

SIMULATE THE ISSUE

1. Create Empty DefaultDict

julia> using DataStructures

julia> a = DefaultDict(0)
DefaultDict{Any, Any, Int64}()

2. Create your struct as dict

julia> struct D1
       data::Dict
       end

3. Assign the default dict to your object

julia> d = D1(a)
D1(Dict{Any, Any}())

4. Update initial default dict

julia> a["A"] = 1
1

5. Check the object and you will see that it was not updated as expected

julia> d.data
Dict{Any, Any}()

HOW TO AVOID THIS BEHAVIOUR

Basically in the data struct instead of using a Dict object use AbstractDict and the issue will not happen. But I think for me this creates some inconsistency in the code. What we should do?

julia> using DataStructures

julia> a = DefaultDict(0)
DefaultDict{Any, Any, Int64}()

julia> struct D2
       data::AbstractDict
       end

julia> d = D2(a)
D2(DefaultDict{Any, Any, Int64}())

julia> a["A"] = 1
1

julia> d.data
DefaultDict{Any, Any, Int64} with 1 entry:
  "A" => 1
@StephenVavasis
Copy link
Contributor

The following is a quote from the manual: (https://docs.julialang.org/en/v1/manual/conversion-and-promotion/#When-is-convert-called?)

convert(T, x) is expected to return the original x if x is already of type T. In contrast, if T is a mutable collection type then T(x) should always make a new collection (copying elements from x).

So I think the behavior you have observed is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants