-
-
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
Add empty
for AbstractArray
s and their types
#33482
base: master
Are you sure you want to change the base?
Conversation
`empty` now works on all `AbstractArray`s and the corresponding call using `Type{<:AbstractArray}`. The method specialized on `AbstractVector` remains for inlining purposes.
The motivation to make |
Assume you have a |
At least In this particular case you can do
It's a good starting point, and I would wait for more feedback before spending time on updating this PR to other methods. |
Hehe, you are right. I was just confused when it didn't work and wanted to patch the hole since most methods usually take types rather than instances (or both).
Thanks for saying that, I will not continue for now, then. However, I had already started and found that writing every method for instances and types was not good design. If this seems worthwhile, maybe having a generic #= @inline ? =# empty(a, types...) = empty(typeof(a), types...) just like for |
@@ -687,6 +688,10 @@ julia> empty([1.0, 2.0, 3.0], String) | |||
``` | |||
""" | |||
empty(a::AbstractVector{T}, ::Type{U}=T) where {T,U} = Vector{U}() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change this method also then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left that in for inlining purposes due to all the existing code depending on it. If that is not necessary, then I'll change it as well.
I also encountered another use case. Pre-allocating a |
I have a few questions for which I don't have solid answers:
|
I'd say yes.
Yes, makes sense.
Hopefully not. Actually that's a question we should also try to address for |
@@ -672,9 +672,10 @@ similar(::Type{T}, shape::Tuple{Union{Integer, OneTo}, Vararg{Union{Integer, One | |||
similar(::Type{T}, dims::Dims) where {T<:AbstractArray} = T(undef, dims) | |||
|
|||
""" | |||
empty(v::AbstractVector, [eltype]) | |||
empty(a::AbstractArray, [eltype]) | |||
empty(a::Type{AbstractArray}, [eltype]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty(a::Type{AbstractArray}, [eltype]) | |
empty(a::Type{<:AbstractArray}, [eltype]) |
@@ -687,6 +688,10 @@ julia> empty([1.0, 2.0, 3.0], String) | |||
``` | |||
""" | |||
empty(a::AbstractVector{T}, ::Type{U}=T) where {T,U} = Vector{U}() | |||
function empty(a::Type{<:AbstractArray{T,N}}, ::Type{U}=T) where {T,N,U} | |||
convert(AbstractArray{U}, a(undef, Tuple(Iterators.repeated(0,N)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately I'm not sure T(undef, dims)
is a required part of the AbstractArray
API. The operation of creating a new array from a type but with a different element type could potentially be handled by similar
(see #20815).
Also this should be faster:
convert(AbstractArray{U}, a(undef, Tuple(Iterators.repeated(0,N)))) | |
convert(AbstractArray{U}, a(undef, ntuple(_ -> 0, N))) |
BTW, better use the short function syntax as for other definitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the ntuple
correction! I actually found that function some days ago and was gonna modify the PR accordingly but you were faster. :)
About the T(undef, dims)
, yeah, sorry; that was stupid since similar
has the dims
argument. I completely forgot about it.
I also love your referenced PR; just today I ran into a case where it would have been useful.
BTW, better use the short function syntax as for other definitions.
Do you mean I should always use empty(x) = ...
? I didn't use it as the functions were getting too wide (over 92 columns) and I thought the short syntax should be avoided when the function spans multiple lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About the
T(undef, dims)
, yeah, sorry; that was stupid sincesimilar
has thedims
argument. I completely forgot about it.
I also love your referenced PR; just today I ran into a case where it would have been useful.
As I noted, the problem with similar
is that it requires an instance, not a type.
Do you mean I should always use
empty(x) = ...
? I didn't use it as the functions were getting too wide (over 92 columns) and I thought the short syntax should be avoided when the function spans multiple lines.
Yes it's fine to break after =
(see examples in this file).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I noted, the problem with similar is that it requires an instance, not a type.
That was the problem with it, I remember... So first we will have to keep the constructor by type, if I'm seeing this correctly? Until #20815 is merged.
Yes it's fine to break after = (see examples in this file).
I was thinking more in an aesthetic/readability sense. Only because it has been done in the past does not imply it has to be done again. But sure, I will change it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I'm not even sure calling the constructor like that is guaranteed to work. Somebody else will have to confirm.
It's usually quite a bad idea to introduce methods that work on both types and instances of types since types are values in Julia so this tends to produce an inherent ambiguity. However, in this case the
|
Hey Stefan, so you are in favour of something like |
Sure, I think that would be fine. |
@janEbert Sorry for neglecting this PR for 4 years. It now has conflicts. If you are still interested and would be willing to update it, I think it could be merged soon? |
Hi Max, sorry from my side; after all I promised to add stuff to the PR but never did. I haven't used Julia deeply in a while but if you are fine with waiting a bit more for me to catch up again, I'll gladly update the PR according to all the 4 amazing years of development. ;) |
@janEbert not your fault. thank you for being willing to pick this up again -- and sure, take your time |
empty
now works on allAbstractArray
s and the corresponding callusing
Type{<:AbstractArray}
.The method specialized on
AbstractVector
remains for inliningpurposes. I'm not sure whether that is actually necessary but I'm sure you can tell. (And maybe also explain how to test for that myself. That would be amazing!)