JuliaLang/julia — pull request #8560 by StefanKarpinski (2014-10-02 20:24:19+00:00)
Title: deepcopy: recurse through immutable objects with mutable fields.

I've encountered a number of cases which have caused me to believe that recursing through immutable types with mutable fields is the right thing to do. One example (currently broken on master), is OrderedDict [1] from DataStructures – this type is a lightweight, immutable wrapper around HashDict [2], which is mutable. The current deepcopy behavior means that doing `od2 = deepcopy(od1)` simply returns `od1`, which is clearly not what is wanted. This could be fixed in the DataStructures package, but I suspect wanting to copy through immutables is the rule, not the exception.

Philosophically, the only coherent way to define at a conceptual level what deepcopy *should* do that I've come up with is that it should be functionally equivalent to serializing and then deserializing an object. That would recursively copy through immutable types with mutable fields, which is another justification for this change.

I *believe* that not sticking immutable objects in `stackdict` is correct, but I'm not 100% sure. My reasoning is that in order for a path from the root of a data structure to have a loop, it has to have passed through a mutable object since otherwise you couldn't have constructed the structure in the first place (unless you cheated, in which case you have only yourself to blame), at which point the deepcopy recursion will stop once that mutable object is reached a second time. There may be some unnecessary copying of immutable objects, but I think it's harmless.

[1] https://github.com/JuliaLang/DataStructures.jl/blob/master/src/ordereddict.jl
[2] https://github.com/JuliaLang/DataStructures.jl/blob/master/src/hashdict.jl