[HN Gopher] Pure vs. Impure Iterators in Go
       ___________________________________________________________________
        
       Pure vs. Impure Iterators in Go
        
       Author : ingve
       Score  : 39 points
       Date   : 2025-05-29 08:57 UTC (2 days ago)
        
 (HTM) web link (jub0bs.com)
 (TXT) w3m dump (jub0bs.com)
        
       | tapirl wrote:
       | Be careful there are bugs and design flaws in Go iterators:
       | https://go101.org/blog/2025-03-15-some-facts-about-iterators...
        
         | jub0bs wrote:
         | Your post does show that iterators are somewhat of a leaky
         | abstraction, but I'm not sure I would go as far as calling some
         | of their infelicities "bugs". Whether those infelicities matter
         | in practice is a moot point.
        
           | tapirl wrote:
           | The bug is confirmed:
           | https://github.com/golang/go/issues/71685
        
             | jub0bs wrote:
             | Ok, that is annoying. I hope it gets fixed soon.
        
       | euroderf wrote:
       | Great! How about iterators on trees ? Multiple options to
       | provide.
        
       | pansa2 wrote:
       | > _Most iterators provide the ability to walk an entire sequence
       | [...] Calling the iterator again walks the sequence again._
       | 
       | > _" Single-use iterators" break that convention, providing the
       | ability to walk a sequence only once._
       | 
       | This seems similar to the difference between an "iterable" and an
       | "iterator" in Python (and between `IEnumerable` and `IEnumerator`
       | in C#).
       | 
       | A Python list `l = [1, 2, 3]` is an _iterable_ , and you can do
       | `for v in l: print(v)` multiple times. But `iter(l)` is an
       | _iterator_ and `for v in i: print(v)` will only work once.
        
         | catlifeonmars wrote:
         | This is the same in JavaScript. There is "pure" Iterable
         | protocol which produces an "impure" Iterator. Interestingly ,
         | for loops in JavaScript do not work directly with Iterators; to
         | use in a for loop you must wrap an Iterator in an Iterable
        
           | codr7 wrote:
           | Java is the same if I remember correctly, always felt like a
           | design failure to me.
        
             | masklinn wrote:
             | It's especially dumb for Java, because Iterator could just
             | have been a subtype of Iterable. That's basically what
             | Python does, the iterator protocol requires also being an
             | iterable[0]. And Rust just blanket implements IntoIterator
             | for every Iterator without asking.
             | 
             | At least it's pretty easy to wrap an iterator in JS:
             | {[Symbol.iterator]: () => it}
             | 
             | [0] which in the rare case you implement an iterator
             | entirely by hand will be a trivial `return self`, so much
             | so that `collection.abc.Iterator` just provides that)
        
         | masklinn wrote:
         | It's more between repeatable iterables and one-shot iterables
         | (of which iterators are a subset, as iterators are iterable).
         | For instance a file is an iterable, but (unless it's seekable
         | and you rewind it) it'll only let you iterate once.
         | 
         | Basically what Go calls an iterator most other language call an
         | iterable. Because it uses internal iteration, Go doesn't hand
         | out iterators (save through iter.Pull).
        
       | catlifeonmars wrote:
       | - My initial thought is that the performance implication (e.g.
       | escaping to the heap) of impure iterators is an implementation
       | detail and seems like a good candidate for a future compiler
       | optimization.
       | 
       | - impure iterators are strictly more powerful than pure iterators
       | in that they _can_ be resumed but do not _have_ to be. If I
       | wanted to pick one pattern for consistent behavior across all
       | iterators it would be this one.
        
         | gregwebs wrote:
         | Not all impure iterators can be resumed. But any pure iterator
         | can be converted to a resumable iterator with a generic
         | conversion function.
        
           | catlifeonmars wrote:
           | > any pure iterator can be converted to a resumable iterator
           | with a generic conversion function.
           | 
           | Makes sense
           | 
           | > Not all impure iterators can be resumed
           | 
           | How do you mean? In my head resuming an iterator is just
           | partially unrolling a loop.
        
             | nine_k wrote:
             | An impure iterator can panic, so you can't resume?
        
       | shubhjain wrote:
       | Are the wordings "pure" vs "impure" suitable here, or should it
       | have been "stateless" vs "stateful"?
        
       ___________________________________________________________________
       (page generated 2025-05-31 23:01 UTC)