Introduce iter package in Go 1.23

How about the new iter package? good or bad for us?

Technology has to be invented or adopted.
— Jared Diamond

Medium Link: Introduce iter package in Go 1.23 | by Wesley Wei | Jun, 2024 | Programmer’s Career

Hello, here is Wesley, Today’s article is about iter package in Go. Without further ado, let’s get started.💪

Introduction

The new iter package introduced in Go 1.23 brings the concept of iterators and language-level support. This iterator is an important feature.

In the iter package, two standard iterator formats are defined:

1
2
3
4
5
6
7
8
// Seq is an iterator over sequences of individual values.
// When called as seq(yield), seq calls yield(v) for each value v in the sequence,
// stopping early if yield returns false.
type Seq[V any] func(yield func(V) bool)
// Seq2 is an iterator over sequences of pairs of values, most commonly key-value pairs.
// When called as seq(yield), seq calls yield(k, v) for each pair (k, v) in the sequence,
// stopping early if yield returns false.
type Seq2[K, V any] func(yield func(K, V) bool)

src/iter/iter.go - go - Git at Google

The main operations are as follows:

1. Provide a unified iterator interface: The iter package defines Seq and Seq2 iterators, the former for iterating single-value sequences, and the latter for iterating key-value pairs. This provides a unified iteration method for various data structures such as arrays, slices, maps, etc.

2. Encapsulate low-level details: Users need not understand the underlying data structures; they only need to use Seq or Seq2 to implement iteration, greatly simplifying the code writing process.

3. Introduction of generics: The iterators in the iter package use the newly introduced generic mechanism, allowing them to handle any type of data, increasing the code’s generality and reusability.

4. Built-in error handling: Errors during iteration can be captured and handled, making the programming safer.

Examples

If we use the new feature to implement printing the Fibonacci numbers less than 1000, the code is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func main() {
fibo := func(yield func(x int) bool) {
f0, f1 := 0, 1
for yield(f0) {
f0, f1 = f1, f0+f1
}
}

for x := range fibo {
if x >= 1000 {
break
}
fmt.Printf("%d ", x)
}
}

Better Go Playground

In this code, yield can be thought of as a filter role, only printing the Fibonacci numbers we are generating when it returns true. This gives the caller (in this case, the main function) a lot of flexibility, as they can decide when to stop generating and printing Fibonacci numbers.

Regarding the use of yield, you can refer to: Iterators in Go — Bitfield Consulting; This article describes an experimental feature to the Go language: range over func. Of course, in Go 1.23, this feature will work directly.
If we used channels in the past, the code would look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func main() {
fibo := func() <-chan int {
ch := make(chan int)
go func() {
f0, f1 := 0, 1
for {
ch <- f0
f0, f1 = f1, f0+f1
if f0 >= 1000 {
close(ch)
break
}
}
}()
return ch
}
for x := range fibo() {
fmt.Printf("%d ", x)
}
}

Clearly, the iter package looks simpler, but for those who are not willing to accept new things, understanding it will be more difficult and will require some cost. This does not conform to the KISS principle held by some people.

Controversy and Thoughts

I’ve always considered Go (and the community) to be very cautious about making languages changes, not to add duplicate ways of representing the same thing. Pushing a cohesive and simple design. I’m curious, is it just me feeling like there is a major shift in principles here and is there anybody else who has had a look at this and thought the built-in channels are the obvious answer here?
reddit.com/r/golang/comments/1dfpx56/am_i_the_only_one_who_thinks_channels_are_the/

Similarly, on iter: new package for iterators · Issue #61897 · golang/go · GitHub, there are some differing opinions.

Although the implementation of the iter package caused some controversy, such as the need for an additional iter.Seq2 for iterating key-value pairs, overall, this feature describes a clear path for standardizing iteration behavior in Go.

In summary, then, iterators are neat.

References

  1. iter: new package for iterators · Issue #61897 · golang/go · GitHub
  2. Iterators in Go — Bitfield Consulting
  3. reddit.com/r/golang/comments/1dfpx56/am_i_the_only_one_who_thinks_channels_are_the/

And I’m Wesley, delighted to share knowledge from the world of programming. 

Don’t forget to follow me for more informative content, or feel free to share this with others who may also find it beneficial. it would be a great help to me.

See you in the next article. 👋

中文文章: https://programmerscareer.com/zh-cn/golang-iter/
Author: Wesley Wei – Twitter Wesley Wei – Medium
Note: Originally written at https://programmerscareer.com/golang-iter/ at 2024-06-16 22:28. If you choose to repost or use this article, please cite the original source.

Time Control You Should Know in Golang Switching Between Different Programming Languages Quickly: VSCode Profiles

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×