Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any plans to add support for Go 1.23's iterators? #525

Open
BooleanCat opened this issue Aug 28, 2024 · 7 comments
Open

Any plans to add support for Go 1.23's iterators? #525

BooleanCat opened this issue Aug 28, 2024 · 7 comments

Comments

@BooleanCat
Copy link

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)
}
@BooleanCat
Copy link
Author

BooleanCat commented Aug 28, 2024

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).

@BooleanCat
Copy link
Author

See #528

@joel-u410
Copy link

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.

@joel-u410
Copy link

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.

@jub0bs
Copy link

jub0bs commented Sep 24, 2024

FWIW, I've produced https://github.com/jub0bs/iterutil:

an experimental collection of utility functions (sources, combinators, sinks) for working with Go iterators

@jub0bs
Copy link

jub0bs commented Sep 24, 2024

@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.

@dashjay
Copy link

dashjay commented Nov 7, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants