Yeah, I agree that it can be counter-intuitive and error-prone depending on your background...
On Sun, Aug 14, 2016 at 3:24 PM, Tommy Hofmann <[email protected]> wrote: > 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]> 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. >>>>>>> >>>>>> >>>>>> >>>>> >>
