IntervalSets.jl
IntervalSets.jl copied to clipboard
Add copy
This PR adds a copy method. The easiest way to do this was to call deepcopy
, @ararslan @timholy is there any hidden issue in doing this?
FWIW, I remember Jeff being opposed to having a copy
for immutable objects, and I think that Base has removed a number of copy
methods already. Eg.
julia> copy((1,2))
ERROR: MethodError: no method matching copy(::Tuple{Int64,Int64})
I think this is a better example:
julia> copy(1:2)
1:2
is there any hidden issue in doing this?
With using deepcopy
, you mean? Not as far as I'm aware. It ensures that BigFloat
s are properly copied because (IIRC) copy(::BigFloat)
is a no-op as it is with the immutable number types, and deepcopy
itself is a no-op for bits types.
Ah I didn't realise BigFloat
behaved like that:
julia> copy(x) === x
true
julia> BigFloat(1) === BigFloat(1)
false
Perhaps I should just do a standard copy
explicitly for Interval
.
If you want to make sure that mutating a BigFloat
in one interval doesn't affect another interval, deepcopy
is probably your best bet.
BigFloat
s are mutable? In that case isn't its copy behaviour a bug?
¯\_(ツ)_/¯
BigFloat is supposed to be semantically immutable but their implementation doesn't let us do that now. copy(1:2)
has to work because it's part of the AbstractArray interface. Given that copy(3)
works then I think it's good to define it for intervals too.
deepcopy
can be a huge performance trap, so I'm a bit opposed to implementing copy
via deepcopy
. What problem did using deepcopy
solve?
I don’t think it actually solves a problem. I’m inclined to change it to
copy(d::Domain) = d
Isn't defining copy
for concrete subtypes like Interval
much safer option? If it's too cumbersome, how about
copy(d::Domain) = isbits(d) ? d : deepcopy(d)
You are certainly right, at least in theory. In practice, I can’t think of a case where it matters.
But for the sake of not intentionally writing “bad“ code I’ll make that change and only override for TypedEndpointsInterval
.