How can a closure iterator manage resources? In my particular case, I have a 
closure iterator that create channels and threads. When the iterator is aborted 
from the caller side, how can I free the resources I have allocated in the 
iterator?

For instance, consider the following example: 
    
    
    import strutils
    import os
    
    proc stream(m: int): iterator: int =
      iterator iter: int {.closure.} =
        var i = 0
        echo "Allocate resources"
        while true:
          yield i
          inc(i)
          if i == m:
            echo "Iterator max reached; end of iterator"
            break
        echo "Deallocate resources"
      
      result = iter
    
    
    proc main =
      let iter = stream(parseInt(paramStr(1)))
      for i in iter():
        echo "i=", i
        if i == 10:
          echo "Aborting iteration in main after 10 items..."
          sleep(2_000)
          break
      echo "Out of iterator in main"
    
    
    echo "Before main"
    main()
    echo "After main"
    
    
    Run

This code creates an iterator that count up to a maximum specified from the 
command line, but after 10 loops the caller procedure aborts the iterator.

If we run it like `./pug 5`, we see that the iterator allocates the resources 
and frees them when it naturally completes. 
    
    
    Before main
    Allocate resources
    i=0
    i=1
    i=2
    i=3
    i=4
    Iterator max reached; end of iterator
    Deallocate resources
    Out of iterator in main
    After main
    
    
    Run

But if we run it like `./pug 15`, we see that the deallocation does not happen: 
    
    
    Before main
    Allocate resources
    i=0
    i=1
    i=2
    i=3
    i=4
    i=5
    i=6
    i=7
    i=8
    i=9
    i=10
    Aborting iteration in main after 10 items...
    Out of iterator in main
    After main
    
    
    Run

Enclosing the iterator code with a `try: ... finally: ...` does not help 
because there are no exceptions in the game. I've looked at the [Nim 
Destructors and Move Semantics](https://nim-lang.org/docs/destructors.html) 
documentation but that does not seem to apply there either.

So, how do I ensure that resources are freed when a closure iterator is out of 
scope?

Reply via email to