-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Make iterate(::Reverse)
use indexing by default
#43110
Conversation
I think the most significant downside I can forsee of this is that if one has a type that does not support indexing, then you may get worse error messages than before. Compare (old) julia> struct Foo
a::Int
b::Int
end
julia> for x ∈ Iterators.reverse(Foo(1, 2))
@show x
end
ERROR: MethodError: no method matching iterate(::Base.Iterators.Reverse{Foo})
Closest candidates are:
iterate(::Union{LinRange, StepRangeLen}) at ~/julia/usr/share/julia/base/range.jl:821
iterate(::Union{LinRange, StepRangeLen}, ::Integer) at ~/julia/usr/share/julia/base/range.jl:821
iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}} at ~/julia/usr/share/julia/base/dict.jl:695
...
Stacktrace:
[1] top-level scope
@ ./REPL[2]:1 against (new) julia> struct Foo
a::Int
b::Int
end
julia> for x ∈ Iterators.reverse(Foo(1, 2))
@show x
end
ERROR: MethodError: no method matching keys(::Foo)
Closest candidates are:
keys(::IndexStyle, ::AbstractArray, ::AbstractArray...) at ~/julia/usr/share/julia/base/abstractarray.jl:350
keys(::Tuple) at ~/julia/usr/share/julia/base/tuple.jl:72
keys(::Tuple, ::Tuple...) at ~/julia/usr/share/julia/base/tuple.jl:77
...
Stacktrace:
[1] eachindex(itrs::Foo)
@ Base ./abstractarray.jl:276
[2] iterate(A::Base.Iterators.Reverse{Foo})
@ Base.Iterators ./REPL[1]:2
[3] top-level scope
@ ./REPL[7]:1 |
I think we should do this in addition to #43106 |
Since |
base/iterators.jl
Outdated
@@ -112,6 +112,15 @@ last(r::Reverse) = first(r.itr) # the first shall be last | |||
(A.itr[idx], (state[1], itrs)) | |||
end | |||
|
|||
# Fallback method of `iterate(::Reverse{T})` which assumes the collection has `getindex(::T) and `reverse(eachindex(::T))` | |||
# don't propagate inbounds for this just in case | |||
function iterate(A::Reverse state=(reverse(eachindex(A.itr)),)) |
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.
function iterate(A::Reverse state=(reverse(eachindex(A.itr)),)) | |
function iterate(A::Reverse, state=(reverse(eachindex(A.itr)),)) |
I guess this could lead to a dispatch loop if an array's index iterator doesn't support reverse
? Maybe ok though.
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.
Maybe use Base.reverse
?
Co-authored-by: Jeff Bezanson <[email protected]>
Our thinking is that implementing |
Co-authored-by: Jeff Bezanson <[email protected]> Co-authored-by: Jeff Bezanson <[email protected]> Co-authored-by: Jameson Nash <[email protected]>
Co-authored-by: Jeff Bezanson <[email protected]> Co-authored-by: Jeff Bezanson <[email protected]> Co-authored-by: Jameson Nash <[email protected]>
With this change we can do things like
I'm proposing this as an alternative to #43106 in order to fix #43101