Description
This proposal is for the addition of a new builtin type, iterator
, and a new package, iter
:
type iterator interface{
Next() (item interface{}, more bool)
}
// Under package iter
// This struct is for extending the basic builtin iterator to support
// a broader and higher level method set.
//
type Iterator struct {
// internals would all be private
}
// An example of a method that this type could provide
func (i Iterator) Map(f func(item interface{}) interface{}) Iterator {}
Why
builtin iterator type
This follows a similar reason as to why error
is a single method interface and not a struct because it allows any implementation to provide the desired behaviour. The behaviour then comes from the definition of an iterator: a producer of items; hence, the single method, Next
. A direct benefit (all be it difficult to document) is that existing builtin types that are iterable can automatically implement the iterator
interface. Thus no wrapper types would have to be created to accommodate the use of, for example, []int
in a function which looks like this func sum(nums iterator) int
.
package iter
Again much like iterator
follows error
, iter
follows the errors
package in the sense that its purpose is to provide utilities for working with iterators. I won't go in to everything that can be built on top of the basic iterator
interface because a quick google search can bring you up to speed on some very common methods like map, reduce, filter, etc. The main reason for including this package is to provide all users with a consistent and convenient package for simplifying their work with iterators.
Some Thoughts
- What about errors? - Should
iterator
actually look likeNext() (interface{}, error)
where no more items would be identified withio.EOF
or possiblyiter.EOI
. - Is this future proof in regards to generics? - Some initial thinking leads me to believe so since ideally it would amount to a change looking like this:
Next() (item T, more bool)
- How useful is this to the greater community really? - I think fairly useful since my (probably wrong) view of the community is one rich with "data processing" (broader sense than just pipelines/aggregation) usage which are workloads that iterators really excel at
For reference, this proposal has been heavily influenced by Rust's implementation of iterators.