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.}

+@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

Reply via email to