Fixed: generator->list etc consumes extra item when number of items is specified #5 Arthur A. Gleckler 23 Jul 2016 21:04 UTC

Thanks to Jeremy Steward, we have just published a fix for
an implementation issue with SRFI 121.  It turns out that
<enami> reported this on Jan 27.  Since we discourage the
use of Github issue trackers, encouraging people to report
problems to the mailing list instead, I didn't notice the
issue report until Jeremy submitted the fix.  Sorry about
that.

So that we have a full record on the mailing list, I'm
copying the Github issue below:

  <https://github.com/scheme-requests-for-implementation/srfi-121/issues/5>

  enami commented on Jan 27

  The generator->list etc consumes extra item when number of items is specified.  It is troublesome when user want to process each n items but don't want to lose any items.

  Here is a example to illustrate the problem (I used gauche but override generator->list with reference implementation version):
  ```
  $ gosh
  gosh> (use gauche.generator)
  #<undef>
  gosh> (define generator->list
          (case-lambda ((gen) (generator->list gen +inf.0))
                       ((gen n)
                        (let ((next (gen)))
                             (if (or (eof-object? next)
                                     (= 0 n))
                                 '()
                                 (cons next (generator->list gen (- n 1))))))))
  generator->list
  gosh> (define g (list->generator '(1 2 3 4 5 6)))
  g
  gosh> (generator->list g 2)
  (1 2)
  gosh> (generator->list g 2)
  (4 5)
  gosh> (generator->list g 2)
  ()
  gosh>
  ```

  Note that item `3` and `6` are lost.  `generator->vector!` also loses an item when vector is exhausted first.

  ```
  $ gosh
  gosh> (use gauche.generator)
  #<undef>
  gosh> (define (generator->vector! vector at gen)
    (let loop ((value (gen)) (count 0) (at at))
      (cond
        ((eof-object? value) count)
        ((>= at (vector-length vector)) count)
        (else (begin
                (vector-set! vector at value)
                (loop (gen) (+ count 1) (+ at 1)))))))
  generator->vector!
  gosh> (define v (make-vector 3))
  v
  gosh> (define g (list->generator '(1 2 3 4 5)))
  g
  gosh> (generator->vector! v 0 g)
  3
  gosh> (g)
  5
  gosh> v
  #(1 2 3)
  gosh>
  ```

  `generator->vector!` returns 3 but actually four items are consumed and item `4` is lost.

SRFI Editor