**So, first questions: What are streams, what are they used for?**

A `Stream` is an abstraction for anything that provide an input stream of 
bytes. A stream of bytes is just a sequence of bytes, obtained one at a time. 
On top of this, many operations can be implemented, such as reading full lines, 
etc.

**So here is my second question: What is happening, and what can I do about 
it?**

I'm not going to try to explain everything that's happening in your code but 
instead provide you with a working (reduced) example of how I would go about 
doing something similar to what you're doing, which is basically trying to pass 
iterators to procs. (Hopefully I understood your need correctly.)
    
    
    import os, streams, zip/gzipfiles
    
    # Convert a stream into an iterator of lines
    proc linesIterator(stream: Stream): iterator(): string =
      result = iterator(): string =
        while not stream.atEnd:
          yield stream.readLine()
    
    # Convert an iterator of strings into a seq of strings
    # (contrived illustration of passing an iterator to a proc)
    proc readAllLines(iter: iterator(): string): seq[string] =
      result = newSeq[string]()
      for line in iter():
        result.add(line)
    
    # Main code
    if paramCount() < 1:
      echo "Usage: stream_example [filename]"
      quit(1)
    let filename = paramStr(1)
    let stream: Stream =
      if filename[^3 .. ^1] == ".gz":
        newGZFileStream(filename)
      else:
        newFileStream(filename, fmRead)
    if stream == nil:
      echo "Unable to open file: " & filename
      quit(1)
    
    let lines = linesIterator(stream)
    let allLines = readAllLines(lines)
    for line in allLines:
      echo line
    stream.close()
    

As you can see above, the `stream` can be either a `FileStream` or a 
`GZipFileStream`, the rest of the program doesn't care because both are streams.

Note that the `linesIterator` proc _returns_ an iterator instead of being an 
iterator itself. (It is a closure iterator because it captures variables from 
the environment, namely the stream parameter but we don't have to explicitly 
annotate this; Nim implicitly figures this out.)

PS: You'll need nimble to compile this program because of the dependency on the 
zip package.

Reply via email to