TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Fun with Go Iterators

161 pointsby xnacly7 months ago

18 comments

openasocket7 months ago
I work with Go a lot at my job, and I definitely prefer functional programming so I chafe at the language a bit. I was excited to incorporate iterators into our code. Unfortunately, I'm also working in an environment where we are memory constrained, so on our hot path we need to not allocate at all. I tried playing with the iterators a bit, and couldn't get it to produce something that didn't allocate. I got close, but as much as a tried I couldn't get below 1 allocation per loop (not per loop iteration, per loop). Which in any other setting would be fine, but not for our use case.
评论 #41801496 未加载
评论 #41803162 未加载
评论 #41803542 未加载
评论 #41819588 未加载
integrii7 months ago
Call me crazy, but I don't like any of this. Make more named functions. Keep your logic flat and explicit. I believe go wants you to code this way as well. Imagine the horrors this kind of function chaining creates. Actually, you don't have to. It's JavaScript.
评论 #41805577 未加载
评论 #41800732 未加载
评论 #41799400 未加载
评论 #41804499 未加载
评论 #41801131 未加载
评论 #41800248 未加载
pragma_x7 months ago
I absolutely love it when we can take advantage of Go&#x27;s type system and add additional traits and behaviors to existing types like this.<p>That said, I noticed something odd here. In order for a module like this to really shine, I think all these operations need to be functionally pure. Right now, some of these mutate the iterator&#x27;s `iter` method mid-stream, which is about as side-effect-ful as you can get.<p>```<p>func (i <i>Iterator[V]) Map(f func(V) V) </i>Iterator[V] {<p>cpy := i.iter<p>i.iter = func(yield func(V) bool) {<p><pre><code> for v := range cpy { v = f(v) if !yield(v) { return } } } return i </code></pre> } ```<p>Unless I&#x27;m misreading that, `i.iter` has new behavior after this call. A better way would be to return a new _iterator_ with the custom iter behavior instead.<p>``` func (i <i>Iterator[V]) Map(f func(V) V) </i>Iterator[V] {<p><pre><code> &#x2F;&#x2F; create a fresh iterator around a custom closure (NewIterator() is hypothetical in this case) return NewIterator(func(yield func(V) bool) { for v := range i.iter { v = f(v) if !yield(v) { return } } }) </code></pre> } ```
评论 #41802383 未加载
评论 #41800724 未加载
kubb7 months ago
Go people will do this and they&#x27;ll be content:<p><pre><code> a := []int{1,2,3,4} it := slices.All(a) it = slices.Reverse(it) it = slices.Map(it) it = slices.Filter(it, func(i int) bool { return i % 2 == 0 }) slices.ForEach(it, func(i int) { fmt.Println(i) }) </code></pre> I don&#x27;t judge the Go enjoyers, but I prefer writing TypeScript to Go which says it all.<p>Type-inferred arrow lambda for function arguments would go such a long way in making this code nicer... And not make compilation slower at all.<p><pre><code> it = slices.Filter(it, i =&gt; i % 2 == 0) slices.ForEach(it, i =&gt; fmt.Println(i))</code></pre>
评论 #41800546 未加载
评论 #41820518 未加载
评论 #41802335 未加载
评论 #41801224 未加载
评论 #41803422 未加载
gtramont7 months ago
Unfortunately the chain approach breaks down when if you need to `map` to a different type, for example. Go does not allow generic typed methods.
评论 #41799500 未加载
评论 #41798834 未加载
pdimitar7 months ago
Might be interesting to make a library that competes with <a href="https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;lo">https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;lo</a>?
评论 #41799475 未加载
评论 #41801521 未加载
评论 #41798723 未加载
评论 #41798798 未加载
indulona7 months ago
&gt; My issue with the go way of iterators is, you can’t chain them like you would in JavaScript<p>You are not supposed to chain them. This addiction to try and chain everything everywhere all the time is so freaking weird and has been for a very long time.<p>Not only you are completely losing grasp on what is going on and write code prone to errors, but you are making it unreadable for other people that will be maintaining or just reading your code who will come long after you are gone from the company or abandon your library.<p>This is where Go&#x27;s simplicity approach and splitting each action into its own for loop or block of code is a godsend for maintainability.
评论 #41805816 未加载
dilap7 months ago
The Reverse implementation seems off to me -- it runs through the iterator twice, once collecting into a slice, and then a second time filling the same slice in reverse. (So basically the first Collect call is only being used to find the length of the iterated sequence.) I&#x27;m not sure about Go conventions†, but I imagine it would be considered better form to only run through the iterator once, reversing the collected slice in-place via a series of swaps.<p>(† Are iterators even expected&#x2F;required to be reusable? If they are reusable, are they expected to be stable?)
评论 #41798929 未加载
评论 #41799258 未加载
评论 #41807706 未加载
mbrumlow7 months ago
&gt; My issue with the go way of iterators is, you can’t chain them like you would in JavaScrip<p>Because it’s not JavaScript, and that is a good thing.
评论 #41801239 未加载
评论 #41800245 未加载
binary1327 months ago
I’m trying to understand whether this is intended to make Go seem bad or whether it’s just coming across that way to me.
评论 #41800230 未加载
vyskocilm7 months ago
Shameless plug. I had experimented with Go iterators a while ago and did a <a href="https:&#x2F;&#x2F;github.com&#x2F;gomoni&#x2F;it">https:&#x2F;&#x2F;github.com&#x2F;gomoni&#x2F;it</a><p>It was updated to 1.23, so it is as idiomatic as I can get. And yes it has a map method between two types. Just a single simple trick used.
评论 #41803179 未加载
Savageman7 months ago
I like how the author uses a test to run arbitrary code, this is exactly how I do it too!
评论 #41811138 未加载
评论 #41807290 未加载
qudat7 months ago
We just released a go pkg that uses the new iter pkg. We were so excited by the interface in large part because of how simple iterators are to use.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;picosh&#x2F;pubsub&#x2F;blob&#x2F;main&#x2F;pubsub.go#L18">https:&#x2F;&#x2F;github.com&#x2F;picosh&#x2F;pubsub&#x2F;blob&#x2F;main&#x2F;pubsub.go#L18</a><p>We have seen in other languages like JS and python the power of iterators and we are happy to see it in Go
tpoacher7 months ago
Since the article is making a not-so-subtle jab at python being unable to do chain operations, I&#x27;m making my annual rounds to point out that implementing simple, straightforward chain functionality in python is as simple as a two-line function definition:<p><pre><code> def chain( Accumulant, *Functions_list ): for f in Functions_list: Accumulant = f( Accumulant ) return Accumulant </code></pre> <a href="https:&#x2F;&#x2F;sr.ht&#x2F;~tpapastylianou&#x2F;chain-ops-python&#x2F;" rel="nofollow">https:&#x2F;&#x2F;sr.ht&#x2F;~tpapastylianou&#x2F;chain-ops-python&#x2F;</a>
skybrian7 months ago
I think it would be more idiomatic to use statements, not expressions. That is, it’s ok to use local variables for intermediate values in a pipeline.
评论 #41799517 未加载
icar7 months ago
This reminds me of RxJS (<a href="https:&#x2F;&#x2F;rxjs.dev&#x2F;" rel="nofollow">https:&#x2F;&#x2F;rxjs.dev&#x2F;</a>)
AndyKluger7 months ago
1. That&#x27;s a good looking Hugo theme!<p>2. Implicitly chain everything all the time!<p>In Factor, you might do it as:<p><pre><code> reverse [ sq ] [ even? ] map-filter [ . ] each </code></pre> Or with a little less optimizing:<p><pre><code> reverse [ sq ] map [ even? ] filter [ . ] each </code></pre> The least obvious thing is that the period is the pretty-print function.
Spivak7 months ago
It&#x27;s funny the author throws a dig at Python for its syntax that actively discourages this kind of code. Like… my guy you&#x27;re not taking the hint. Python makes things it doesn&#x27;t want you to do ugly as sin. It&#x27;s why lambda is so awkward and clunky.
评论 #41800986 未加载
评论 #41800627 未加载
评论 #41800606 未加载