Iteration in Julia can be achieved for a new defined type by implementing the iteration interface that has the 3 functions: start
, next
, done
I see no exclamation point on the end of those functions so from my understanding of julia naming conventions these 3 functions should not modify their arguments. In particular these two loops should give the same output
state = start(iter)
while !done(iter, state)
(i, state) = next(iter, state)
@show i
end
state = start(iter)
while !done(iter, state)
(other_i, other_state) = next(iter, state)
(i, state) = next(iter, state)
@show i
end
Am I wrong? I ask because I bumped into some iterators in external julia packages not respecting this.
If possible, those functions are not supposed to mutate the iterator (such that the iterator state can be copied and re-used). However, there are some prominent examples where such a design is not possible, or only possible with significant performance penalties. The prime example of this is Base.Task
, which is iterable (each iteration running until the next produce
statement):
julia> collect(@async for i = 1:10
produce(i)
end)
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
In those cases we've generally been fine with mutation (though of course any use of the iteration protocol that caches states won't work). The exclamation point at the end of functions is a convention, but is not enforced in any way (and is not strictly limited to mutation of its input arguments, but rather having some side effect that you want to make sure the programmer is aware of).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With