lo
lo copied to clipboard
Any plans to add support for Go 1.23's iterators?
Hi there! You're probably aware that Go 1.23 added support for iterators to the standard library with iter.Seq. Many of the features of this library could be adapted to natively support range over functions.
I'd even be happy to work on this feature set. I main go-functional, which is exactly what I described above so many of the iterators from go-functional could be copied over with little modification to support an iter subpackage in this repo for example.
It would support beheaviour like this from go-functional:
for i := range it.Take(it.NaturalNumbers[int](), 3) {
fmt.Println(i)
}
As an example, IndexOf could look like this in a new iter subpackage:
//go:build go1.23
package iter
// IndexOf returns the index at which the first occurrence of a value is found in a sequence or return -1
// if the value cannot be found.
func IndexOf[T comparable](delegate func(func(T) bool), element T) int {
index := 0
for item := range delegate {
if item == element {
return index
}
index++
}
return -1
}
(The build constraint will make sure this file is only compiled for folks using Go 1.23 or higher).
See #528
FWIW, I have written a few of these also, and would be happy to contribute: Map, Flatten (operates over iterators of iterators), FlattenSlice (operates over iterators of slices), FlatMap, FlatMapSlice, Uniq, UniqBy, and Chain.
I also did some benchmarking, and found that when chaining a few operations (like a couple Maps, then a UniqBy, and a Reduce, etc.) over large collections (e.g. ~100,000) the iterator versions of these were in the vicinity of 10% faster than the slice-based lo equivalents. (And sometimes nearly identical)
I was honestly a little surprised the performance improvement wasn't greater.
FWIW, I've produced https://github.com/jub0bs/iterutil:
an experimental collection of utility functions (sources, combinators, sinks) for working with Go iterators
@joel-u410
I was honestly a little surprised the performance improvement wasn't greater.
Have you benchmarked heap allocations too? I expect a big difference, esp. for long combinator chains.
I think if we import iter.Seq/iter.Seq2, the implement may be easy, but the performance for inplace operations like Reverse, Replace should drop a lot
So something I just noticed: iterator variants of First, FirstOr etc. functions would very helpful too.
It is available here: it/find.go:387 and it/find.go:406
I'm closing this issue since the initial effort on iterators is done.
Please open new issues for new helpers ;)