Why no `last(::Generator)`?

Is there a good reason, why last is not implemented for Generators?

I came up with

function Base.last(iter::Base.Generator)
    x = last(iter.iter)
   return iter.f(i)
end

which does exactly what I would expect (and also in O(1) time, like the default implementation of last(a) = a[end].

If this has simply been overlooked in the past, should I open a PR?

Quick example
Without my implementation the current situation is

julia> iter = (i^2 for i in 1:10)
julia> last(iter)
ERROR: MethodError: no method matching lastindex(::Base.Generator{UnitRange{Int64}, var"#1#2"})
Closest candidates are:
  lastindex(::Any, ::Any) at abstractarray.jl:348
  lastindex(::Core.SimpleVector) at essentials.jl:598
  lastindex(::Tuple) at tuple.jl:26

and after defining it we get


julia> iter = (i^2 for i in 1:10)
julia> last(iter)
100

as desired.

I believe that is because general iterators are not required to have finite length.

1 Like

See Getting the last element of an iterator for a previous discussion.

See also Support indexing with generators by omus · Pull Request #37648 · JuliaLang/julia · GitHub

2 Likes

The discussion in the PR answers my question. Thanks!