[racket-dev] [PATCH] add in-slice sequence
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))))
>