Further, it doesn't seem to me to allow you to do anything you can't currently do with blocking channels and/or state.
Further, it doesn't seem to me to allow you to do anything you can't currently do with blocking channels and/or state.
I’ve used iterators similar to what’s described in this article to avoid allocations in critical code paths, but this would make those much less awkward to use (particularly with the upcoming range iterator language change).
> func Pull[V any](push func(yield func(V) bool)) (pull func() (V, bool), stop func()) {
> copush := func(more bool, yield func(V) bool) V {
The main power of Go to me was always quickly being able to read and understand code. This type of coding has a lot of cognitive load to a reader, I feel.
Fwiw if you look at the source of some other idiomatic standard library functions you may find their implementation is of similar complexity. That’s the nature of good abstractions, though, they should make tricky things easy to use.
Channels are slow for no good reason when they aren't wrapping blocking operations.