[racket-dev] [PATCH] add in-slice sequence

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Fri Dec 16 10:59:02 EST 2011

This looks useful to me.

I think this belongs in `unstable/sequence' for now, with the other
new sequence constructors.

I'll merge it.

Thanks for the patch!

Vincent


At Thu, 15 Dec 2011 22:47:44 -0500,
David Vanderson wrote:
> 
> I only got one comment (thanks John), so I'm resending for more 
> feedback.  Is there any interest in adding this, or does everybody do it 
> a better/different way?
> 
> 
> A more motivated example would be showing a list of products on a 
> webpage in batches:
> 
> (define products '(a b c d e f g))
> (for/list ([s (in-slice 3 products)])
>    `(ul ,@(for/list ([e s])
>              `(li ,e))))
> 
> Thanks,
> Dave
> 
> On 12/09/2011 02:46 AM, David Vanderson wrote:
> > Hello,
> >
> > I was trying to write some code to process a few items at a time from 
> > a list.  Nothing I came up with looked great, so I wrote an "in-slice" 
> > sequence function:
> >
> > > (for/list ([e (in-slice 3 (in-range 8))]) e)
> > '((0 1 2) (3 4 5) (6 7))
> >
> > Patch below.  Comments?
> >
> > Thanks,
> > Dave
> >
> >
> >
> > diff --git a/collects/racket/private/for.rkt 
> > b/collects/racket/private/for.rkt
> > index 88733ca..9e032fa 100644
> > --- a/collects/racket/private/for.rkt
> > +++ b/collects/racket/private/for.rkt
> > @@ -51,6 +51,7 @@
> >
> >               in-sequences
> >               in-cycle
> > +             in-slice
> >               in-parallel
> >               in-values-sequence
> >               in-values*-sequence
> > @@ -984,10 +985,30 @@
> >      (if (and (pair? sequences) (null? (cdr sequences)))
> >          (car sequences)
> >          (append-sequences sequences #f)))
> > +
> >    (define (in-cycle . sequences)
> >      (check-sequences 'in-cycle sequences)
> >      (append-sequences sequences #t))
> >
> > +  (define (in-slice k seq)
> > +    (when (not (exact-positive-integer? k))
> > +      (raise (exn:fail:contract "in-slice length must be a positive 
> > integer"
> > +                              (current-continuation-marks))))
> > +    (check-sequences 'in-slice (list seq))
> > +    (make-do-sequence
> > +     (lambda ()
> > +       (define-values (more? get) (sequence-generate seq))
> > +       (values
> > +        (lambda (_)
> > +          (for/list ((i k)
> > +                     #:when (more?))
> > +            (get)))
> > +        values
> > +        #f
> > +        #f
> > +        (lambda (val) (0 . < . (length val)))
> > +        #f))))
> > +
> >    (define (in-parallel . sequences)
> >      (check-sequences 'in-parallel sequences)
> >      (if (= 1 (length sequences))
> > diff --git a/collects/scribblings/reference/sequences.scrbl 
> > b/collects/scribblings/reference/sequences.scrbl
> > index d3ecdfb..6192761 100644
> > --- a/collects/scribblings/reference/sequences.scrbl
> > +++ b/collects/scribblings/reference/sequences.scrbl
> > @@ -298,6 +298,16 @@ in the sequence.
> >    demanded---or even when the sequence is @tech{initiate}d, if all
> >    @racket[seq]s are initially empty.}
> >
> > + at defproc[(in-slice [length exact-positive-integer?] [seq sequence?]) 
> > sequence?]{
> > +  Returns a sequence where each element is a list with 
> > @racket[length] elements
> > +  from the given sequence.
> > +
> > +  @examples[
> > +  (for/list ([e (in-slice 3 (in-range 8))]) e)
> > +  ]
> > +
> > +  }
> > +
> >  @defproc[(in-parallel [seq sequence?] ...) sequence?]{
> >    Returns a sequence where each element has as many values as the number
> >    of supplied @racket[seq]s; the values, in order, are the values of
> > diff --git a/collects/tests/racket/for.rktl 
> > b/collects/tests/racket/for.rktl
> > index 691e309..6c883b8 100644
> > --- a/collects/tests/racket/for.rktl
> > +++ b/collects/tests/racket/for.rktl
> > @@ -84,6 +84,15 @@
> >  (test #t sequence? (in-cycle))
> >  (test #t sequence? (in-cycle '()))
> >
> > +(test #t sequence? (in-slice 1 '()))
> > +(test '() 'empty-seq (for/list ([v (in-slice 1 '())]) v))
> > +(test '((0 1)) 'single-slice (for/list ([v (in-slice 3 (in-range 
> > 2))]) v))
> > +(test-sequence [((0 1 2) (3 4 5))] (in-slice 3 (in-range 6)))
> > +(test-sequence [((0 1 2) (3 4 5) (6 7))] (in-slice 3 (in-range 8)))
> > +(test-sequence [((0 1 2) (3 4 5) (6 7 8)) (0 1 2)]
> > +                (in-parallel (in-slice 3 (in-naturals)) (in-range 3)))
> > +(err/rt-test (for/list ([x (in-slice 0 (in-range 8))]) x) 
> > exn:fail:contract?)
> > +
> >  (test-sequence [(0 1 2) (a b c)] (in-parallel (in-range 3) (in-list 
> > '(a b c))))
> >  (test-sequence [(0 1 2) (a b c)] (in-parallel (in-range 10) (in-list 
> > '(a b c))))
> >  (test-sequence [(0 1 2) (a b c)] (in-parallel (in-range 3) (in-list 
> > '(a b c d))))
> >
> _________________________________________________
>   For list-related administrative tasks:
>   http://lists.racket-lang.org/listinfo/dev


Posted on the dev mailing list.