Yes, you are right. When we started with julia and did the deepcopy for our own types, we (apparently) did not read the manual and just overloaded the deepcopy function. This introduced lots of nasty bugs.
On Sunday, August 14, 2016 at 9:15:46 PM UTC+2, Cedric St-Jean wrote: > > AFAIK deepcopy should never be overloaded. From the docstring: > > While it isn't normally necessary, user-defined types can override the >> default deepcopy behavior by defining a specialized version of the >> function deepcopy_internal(x::T, dict::ObjectIdDict) (which shouldn't >> otherwise be used), where T is the type to be specialized for, and dict >> keeps track of objects copied so far within the recursion. Within the >> definition, deepcopy_internal should be used in place of deepcopy, and >> the dict variable should be updated as appropriate before returning. >> > > > On Sun, Aug 14, 2016 at 3:03 PM, Tommy Hofmann <[email protected] > <javascript:>> wrote: > >> But for users the following might be surprising: If a user defines >> deepcopy(::T) for a user defined type T and x is of type Array{T, 1}, then >> deepcopy(x) is not the "same" as [ deepcopy(z) for z in x]. At least this >> is my experience and how I understand deepcopy.jl. >> >> >> On Sunday, August 14, 2016 at 8:31:20 PM UTC+2, Cedric St-Jean wrote: >>> >>> instead, it puts the same object (which is a copy) in the first and >>>> third positions and you get the same behavior. Maybe this is not the >>>> intended behavior of deepcopy? >>>> >>> >>> It's intentional. deepcopy has to keep and update a dictionary as it >>> traverses the datastructure in order to provide the behaviour. Without it, >>> it would be impossible to copy cyclic data-structures, as the recursive >>> traversal would never end. >>> >>> On Sunday, August 14, 2016 at 11:36:04 AM UTC-4, Tommy Hofmann wrote: >>>> >>>> Indeed, the behavior of deepcopy with respect to arrays of user defined >>>> types is surprising. >>>> >>>> If you define >>>> >>>> Base.deepcopy_internal(x::MyType, ::ObjectIdDict) = >>>> MyType(deepcopy(x.a)) >>>> >>>> then deepcopy(MyType_Vec[[1, 3, 1]]) gives a new object with >>>> "independent" elements. See also >>>> http://docs.julialang.org/en/release-0.4/stdlib/base/#Base.deepcopy >>>> >>>> >>>> On Friday, August 12, 2016 at 8:56:32 PM UTC+2, Josh Langsfeld wrote: >>>>> >>>>> For your second question, I would have expected just doing >>>>> deepcopy(MyType_Vec[[1,3,1]]) would have created a new array with a >>>>> new object allocated for each element. Instead, it puts the same object >>>>> (which is a copy) in the first and third positions and you get the same >>>>> behavior. Maybe this is not the intended behavior of deepcopy? >>>>> >>>>> You can easily get around though this by explicitly calling deepcopy >>>>> on each element directly: MyType_Vec = map(deepcopy, >>>>> MyType_Vec[[1,3,1]]). A similar alternative with an array >>>>> comprehension would be: MyType_Vec = [deepcopy(MyType_Vec[i]) for i >>>>> in [1,3,1]]. >>>>> >>>>> (an array comprehension also answers your first question: MyType_Vec >>>>> = [MyType([0.0]) for i=1:3]) >>>>> >>>>> On Friday, August 12, 2016 at 11:47:39 AM UTC-4, Jan wrote: >>>>> >>>>> I have a beginner question for which I cannot find the answer after >>>>>> quite some searching. >>>>>> >>>>>> >>>>>> type MyType >>>>>> a::Array{Float64,1} >>>>>> end >>>>>> >>>>>> # Fill an array with "independent" instances of MyType. (By the way, >>>>>> is there a shorter way to do this?) >>>>>> >>>>>> MyType_Vec = Array(MyType, 3); >>>>>> >>>>>> for i in eachindex(MyType_Vec) >>>>>> >>>>>> MyType_Vec[i] = MyType([0.0]); >>>>>> >>>>>> end >>>>>> >>>>>> MyType_Vec >>>>>> >>>>>> # Change the value of MyType_Vec[1].a[1] to 2. >>>>>> >>>>>> MyType_Vec[1].a[1] = 2; >>>>>> >>>>>> MyType_Vec >>>>>> >>>>>> # Shuffle the vector but with repeated elements >>>>>> >>>>>> MyType_Vec = MyType_Vec[[1,3,1]]; >>>>>> >>>>>> # Change the value of MyType_Vec[1].a[1] to 4. >>>>>> >>>>>> MyType_Vec[1].a[1] = 4; >>>>>> >>>>>> MyType_Vec >>>>>> >>>>>> # The value of MyType_Vec[3].a[1] also changed to 4. >>>>>> >>>>>> >>>>>> How can I avoid this reference behaviour? I want that, after the >>>>>> shuffling step, the 3 elements of MyType_Vec should be "independent" so >>>>>> that if I change MyType_Vec[1].a[1] nothing else is affected. I have >>>>>> tried copy and deepcopy without success. >>>>>> >>>>>> I would be very happy if someone could help me out. I'm stuck... >>>>>> >>>>>> Many thanks in advance. >>>>>> >>>>> >>>>> >>>> >
