>From: Per Bothner <xxxxxx@bothner.com>
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 ...))