-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Array(...)
(and constructors for all collection types) should always make copies
#23107
Comments
This might be a |
What about the -(::Type{T})(arg) where {T} = convert(T, arg)::T
+(::Type{T})(arg::T) where {T} = copy(arg)
+(::Type{T})(arg) where {T} = convert(T, arg)::T ??? |
Here's a survey of what happens calling mutable structs' own constructors on themselves : julia> tas = [
(Array, [1,2,3]),
(BitArray, 2),
(SharedArray, [1,2,3]),
(Dict, 2 => "a"),
(ObjectIdDict, 2 => "a"),
(Set, "a"),
(Task, () -> rand(9)),
(Channel, 2),
(WeakRef, "a"),
(Ref, "a"),
(Regex, "^a"),
(IOStream, "a"),
(IOBuffer, "a")
];
julia> for (t, a) in tas
print(t, "\n ")
x = t(a)
y = t(x)
println(x === y)
end
Array
true
BitArray
true
SharedArray
true
Dict
false
ObjectIdDict
false
Set
false
Task
false
Channel
true
WeakRef
false
Ref
true
Regex
true
IOStream
true
Base.AbstractIOBuffer{Array{UInt8,1}}
true |
Yikes, that's a bit haphazard. |
Very occasionally, the overlap between conversion and construction is annoying. While the default method for construction calling My point being that given that generic code may be dependent on aliasing behaviour, generally it would be great if each function had documented aliasing guarantees. I'm not sure the current set of functions is built around this idea (for constructors, convert, and many others too)... Thinking aloud, perhaps a trait or something could describe the aliasing relationship between two types through @JeffBezanson While, yes, constructors may tend to allocate new objects, many are immutable wrappers (I'm thinking |
...or constructors are only allowed not to copy their input if it is wrapped in a |
@martinholters see #15120... The fact that the fallback constructor doesn't call Thanks for the analysis @garborg . I wouldn't necessarily apply this issue to non-collections like Whatever else is decided here, it's very clear to me that I agree that some types like
Here I'm explicitly constructing a specific type of mutable collection. My function expects an iterator of pairs. It seems to work. But one day somebody passes an argument that's already a |
Array(...)
(and constructors for all collection types) should always make copies
I should point out that |
This would also be fixed by #15120, since |
To me, it would seem logical if |
We could do that, but I'm more worried about the idea of deprecating |
In the extreme case we would have to since a tuple of ints is a valid iterable that people might want to collect in an array. I'm not loving that aspect but the keyword arg version is at least very easy to read (though much less concise!). Would be an extremely annoying deprecation if we did this so not sure if it's truly worth the effort or not... |
fix #23107, ensure `Array` constructor always makes new arrays
The behavior between
Dict
and anArray
is inconsistent when it comes to when copying is made:In my opinion,
Dict(::Dict)
should not make a copy if it can just return the dict.Reported originally at: https://discourse.julialang.org/t/why-is-d-dict-dict-d/5197
The text was updated successfully, but these errors were encountered: