[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SRFI 121: Generators

This page is part of the web mail archives of SRFI 121 from before July 7th, 2015. The new archives for SRFI 121 contain all messages, not just those from before July 7th, 2015.



From: Per Bothner <per@xxxxxxxxxxx>
Subject: Re: SRFI 121: Generators
Date: Sat, 07 Feb 2015 07:25:01 -0800

> I think formalizing the concept of  generator makes a lot of sense.
> However, I'm scared of adding yet another library with dozens of
> procedures.

That's a valid concern.  I made Gauche's generator library
because I realized I'd written those patterns repeatedly.
However, I did also notice I ended up a lot of similar
procedures in the generator library and lazy-sequence library.

And lazy-sequences are more convenient in general, if the
performance isn't much concern.  I often find myself using
generators just as the basis of lazy seqnece (In Gauche,
generator->lseq can convert a generator to a lazy sequence,
and that is a *lot* more efficient way to create lazy sequences
than recurse with lazy-cons).

From my experience, the most useful utilities over generators
are in the consumer side, e.g. generator-for-each, generator-fold,
generator-let*, do-generator etc.  I suspect any of you have
written (let loop ((item read)) (if (eof-object? item) ...)) pattern
enough times.  An extension of srfi-42 to take generators is also handy.
 
So, instead of putting all those generator-generating procedures,
we can just focus on those two areas:

  - generator->stream, to convert generator to lazy stream
    (maybe srfi-41; or will we have another one in R7RS-large?)
  - consumer patterns; generator-for-each, do-generator etc.


> However, I have concerns about resource reclamation. For example if
> you do
> (using Racket syntax):
>   (for ((x in-producer read-my-file)) ... x ...)
> then the overflying my-file doesn't get closed automatically

Lazy sequences also have this problem, and I think this issue
should be discussed separately.   In general, resouce management
can be decoupled with usage of generators, e.g.

(with-input-from-file my-file
  (lambda ()
    ... using 'read-char' as a generator ...))