[plt-dev] Some additions

From: Eli Barzilay (eli at barzilay.org)
Date: Sun Apr 5 23:55:27 EDT 2009

On Apr  5, Carl Eastlund wrote:
> On Sun, Apr 5, 2009 at 10:07 PM, Eli Barzilay <eli at barzilay.org> wrote:
> >
> > * `in-cycle' -- similar to `in-sequences', but the sequences are
> >  repeated in an infinite loop.  Note that unlike Sam's version
> >  this does not cache the values -- it looks to me like a dangerous
> >  implicit behavior when you can achieve it explicitly by
> >  collecting the list first explicitly.  For example, to cycle a
> >  file's contents you can read it first with `file->bytes'.
> 
> That greatly changes the behavior of in-cycle, Eli.  First of all,
> it means every imperative sequence needs to come with a list- or
> vector-generating version to do manual caching.

You can get the caching behavior from the non-caching cycle in a
straightforward way:

  (define-syntax-rule (in-caching-cycle seq ...)
    (in-cycle (in-list (for/list ([x (in-sequences seq ...)])
                         x))))

but you cannot get the non-caching cycle from the caching one.


> Secondly, it means imperative sequences have no way of doing
> on-demand in-cycle: the whole sequence will be read before
> processing the elements, instead of reading elements one at a time.

Right -- but is there any *practical* use case where you'd want that?
That is, is there any case where some code is willing to potentially
cache a large list but needs to do so as needed.

The thing is that in contrast to this limitation there is the other
side, which is a problem with the caching version:

> Third, there will be no way to run in-cycle on potentially infinite
> imperative sequences, even though it would be nice to have the
> behavior of "process as long as there's something new, or loop if
> there's not".

if caching does happen, then you cannot use `in-cycle' on a
potentially infinite imperative sequence too -- since that will
accumulate the infinite list.  (Right now, it *is* possible to do
that.)

The bottom line is that not caching seems like a much healthier
default for two reasons:

1. It's the least surprising of the two options.

2. "Most" practical cases of needing to cycle over a sequence are
   cases where there is no need to get both caching behavior and a
   lazy by-need use of the cycled sequence.

The "most" in the last item refers to use cases that I know about.  If
there are cases where it is needed (for *practical* reasons), then
I'll add either a keyword or another binding for the caching version.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!


Posted on the dev mailing list.