Don’t Be An Iter-hater!

Status: In Progress

This note is based on this talk

Golang 1.23 added a “first class” iterator concept. The addition itself, as well as the implementation, was a bit controversial. The talk and this note attempt to demystify some use cases for iterators and to provide a bit of a framework around how to write a custom iterator in Go, without making any value judgements around having iterators in the language or the specific implementation chosen.

What Are Iterators?

An iterator is just a mechanism for “going through” (iterating over) a sequence of values. That’s really it!

Imagine I have some array, slice, set, sequence or vector of elements. A classic example might be a bunch of files on disk to be processed.

// pseudocode - no Go yet
["Dockerfile", "README.md", "src", "test"]

Now imagine we want to go through these elements to operate on them for some reason. We might transform them to some other value. We might choose to keep some and discard others We might run some code on them which results in side effects. All very common operations in programming.

// still pseudocode
for element in iterate_over(["Dockerfile", "README.md", "src", "test"]) {
    // transform to another value, e.g. absolutise the path
    // filter out items, e.g. remove directories keep only files
    // cause some side effect, e.g. delete the file
}

We’ll call the bit between the curly braces here, which is being repeatedly run, the body of the for loop.

In the for loop we are iterating over a sequence of elements. The body is run on each one. The mechanism we use to get the actual elements to be iterated over in a certain order is frequently called an iterator in various programming languages.

To function, this for loop needs to know two things.

These two things correspond to the basic functions of iterators, which usually provide

Iterators In Other Languages

Before we dive into how iterators work in Go, it’s worth remembering that iterators are very common concept present in most modern programming languages. Since most Gophers have worked with/in programming languages other than Go, it can be interesting/helpful to have these familiar patterns in mind.

TODO: discuss the following

- iterators in other languages
- iterator/for loop interchangeability
- iterator interfaces in Go 1.23
- re-implementing for range with 1 value
- re-implementing for range with 2 values
- anatomy/patterns of a Go iterator
- eagerness vs laziness
- application to infinite/unbounded sequences