iterators

122 views
Skip to first unread message

Charles Forsyth

unread,
Mar 7, 2026, 6:50:16 PM (3 days ago) Mar 7
to golang-nuts
I was building a little Go package that iterates over some structure,
internally just a []*Thing. 

In the old days in Go, as I've done in several languages
even when they had iterators, I'd have done something like
an Each function that takes a function f (actual could be closure) that it applies
to each thing. It's a few lines of code to write, almost without thinking, and I quickly
know what it does, how it works and what it costs.

Still, sitting here tonight, isn't this now supposed to be an iterator?
Then users can do for ... range ...  instead of calling Each(func(...)...) to (say) find the thing.

On looking at the existing docs, I felt I was quickly heading into a world of pain, which I really have never found with Go (there were things I disliked but I was wrong and recanted years ago). I googled about the pain and as often happens I was not the only one:
hits quite a few of the things that occurred to me and hints at the need for something
to say what to do.

Is there a good summary of what to do? Normally now I use grok but this is Go and
I'm hoping I don't need to be an LLM to make sense of it.

(Aside: In an Ada app I replaced the use of Ada's standard library hash-map packages by the few dozen lines of code to implement a straightforward hash-map, because I discovered the generic Ada one generated something like 60,000 lines of machine instruction, many of which were there to provide bookmarking of open iterators to be able to invalidate them if something changed. I don't know whether Go tries to do that.)

Mikk Margus

unread,
Mar 7, 2026, 7:09:02 PM (3 days ago) Mar 7
to golan...@googlegroups.com
For this specific case, you could probably just use slices.Values(),
such as in https://go.dev/play/p/F0NsfwSRvuL
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts...@googlegroups.com <mailto:golang-
> nuts+uns...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/golang-
> nuts/4782cfdc-4d43-4b38-8e4e-3af2ba0bcf4fn%40googlegroups.com <https://
> groups.google.com/d/msgid/golang-
> nuts/4782cfdc-4d43-4b38-8e4e-3af2ba0bcf4fn%40googlegroups.com?
> utm_medium=email&utm_source=footer>.

Charles Forsyth

unread,
Mar 7, 2026, 7:17:03 PM (3 days ago) Mar 7
to golang-nuts
Thank you for your quick response, under 4 minutes. I like this group. That's very useful. The underlying structure is a little more elaborate, I was trying to simplify it for the post.

Charles Forsyth

unread,
Mar 7, 2026, 7:24:36 PM (3 days ago) Mar 7
to golang-nuts
In fact, in this particular case I can probably do the same as the source for slices.Values, since it's basically the old Each operation
with some attention to types.


Ian Lance Taylor

unread,
Mar 8, 2026, 1:03:26 AM (2 days ago) Mar 8
to Charles Forsyth, golang-nuts
On Sat, Mar 7, 2026 at 3:50 PM Charles Forsyth
<charles...@gmail.com> wrote:
>
> I was building a little Go package that iterates over some structure,
> internally just a []*Thing.
>
> In the old days in Go, as I've done in several languages
> even when they had iterators, I'd have done something like
> an Each function that takes a function f (actual could be closure) that it applies
> to each thing. It's a few lines of code to write, almost without thinking, and I quickly
> know what it does, how it works and what it costs.
>
> Still, sitting here tonight, isn't this now supposed to be an iterator?
> Then users can do for ... range ... instead of calling Each(func(...)...) to (say) find the thing.
>
> On looking at the existing docs, I felt I was quickly heading into a world of pain, which I really have never found with Go (there were things I disliked but I was wrong and recanted years ago). I googled about the pain and as often happens I was not the only one:
> https://github.com/golang/go/issues/71901
> hits quite a few of the things that occurred to me and hints at the need for something
> to say what to do.
>
> Is there a good summary of what to do? Normally now I use grok but this is Go and
> I'm hoping I don't need to be an LLM to make sense of it.

Does it help to read or watch https://go.dev/blog/range-functions ?

> (Aside: In an Ada app I replaced the use of Ada's standard library hash-map packages by the few dozen lines of code to implement a straightforward hash-map, because I discovered the generic Ada one generated something like 60,000 lines of machine instruction, many of which were there to provide bookmarking of open iterators to be able to invalidate them if something changed. I don't know whether Go tries to do that.)

Go does not try to do that. The behavior of iteration on a container
that is being modified will depend on the container.

Ian

Charles Forsyth

unread,
Mar 8, 2026, 9:25:58 AM (2 days ago) Mar 8
to golang-nuts
>Does it help to read or watch https://go.dev/blog/range-functions ?

that looks useful, thanks

Charles Forsyth

unread,
Mar 8, 2026, 12:25:35 PM (2 days ago) Mar 8
to golang-nuts
It was just my mistake in not reading the language specification carefully first,
instead getting stuck in with package iter and subsequent questions about it.
For what I'm doing there is no pain; it's simple.

roger peppe

unread,
6:17 AM (3 hours ago) 6:17 AM
to Charles Forsyth, golang-nuts
On Sat, 7 Mar 2026 at 23:50, Charles Forsyth <charles...@gmail.com> wrote:
In the old days in Go, as I've done in several languages
even when they had iterators, I'd have done something like
an Each function that takes a function f (actual could be closure) that it applies
to each thing. It's a few lines of code to write, almost without thinking, and I quickly
know what it does, how it works and what it costs.

As I'm sure you understand now, that is essentially what an iterator in Go is, just phrased in a standard way, hence allowing standard helper functions (eg. slices.Collect) and with the added syntactic sweetness of being able to use it in a for loop with break, continue and return statements.

The only significant wrinkles to my mind are the unfortunate overhead of iter.Pull (still much faster than starting a goroutine but lots slower than regular iteration) and the fact that no-one can decide what to do about iterators that fail (I quite like (iter.Seq2[T, error] but it's still not entirely satisfactory).

Reply all
Reply to author
Forward
0 new messages