Implementing iterative algorithms using Base.Iterators concepts

I was noticing that some packages implement their iterative algorithms using the Base.Iterators methods by defining the algorithm iteration inside an iterate function and then using that to iterate it. Others implement explicit for/while loops to iterate the algorithm.

That got me wondering, is there a benefit to using the Base.Iterators approach over writing out explicit loops for the algorithm?

Implementing Base.iterate is what enables the for syntax. I’m not sure what you mean by explicit for/while loops, but I’m thinking you refer to when indexing is possible, like looping over an array using something like for i in 1:length(array).

One advantage of iterate is that you don’t have to support indexing which often is more complicated than iteration. Sometimes it also just makes alot of sense from an API point of view.

Contrived example with an utterly pointless iterator which represents an infinite sequence of random numbers just to show an example when indexing is not needed:

julia> struct RandSeq
       seed::Int
       end

julia> import Random

julia> Base.iterate(itr::RandSeq, state=Random.MersenneTwister(itr.seed)) = return randn(state), state

julia> randseq = RandSeq(1)
RandSeq(1)

julia> for v in Iterators.Take(randseq, 5)
       @show v
       end
v = 0.2972879845354616
v = 0.3823959677906078
v = -0.5976344767282311
v = -0.01044524463737564
v = -0.839026854388764

julia> for v in Iterators.Take(randseq, 5)
       @show v
       end
v = 0.2972879845354616
v = 0.3823959677906078
v = -0.5976344767282311
v = -0.01044524463737564
v = -0.839026854388764

An interesting blog post on the subject
https://lostella.github.io/2018/07/25/iterative-methods-done-right.html

3 Likes

that’s really. are there performance penalties at all?