From cb341e1f4860e8064030080ddcdf249bac21429d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 28 Nov 2011 10:18:28 -0700 Subject: [PATCH] make `in-sequences' and `in-cycle' accept 0 sequences Plus doc clarifications. --- collects/racket/private/for.rkt | 16 ++++++++-------- collects/scribblings/reference/sequences.scrbl | 17 ++++++++++++----- collects/tests/racket/for.rktl | 7 +++++++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/collects/racket/private/for.rkt b/collects/racket/private/for.rkt index 3742646232..88733cac4a 100644 --- a/collects/racket/private/for.rkt +++ b/collects/racket/private/for.rkt @@ -979,14 +979,14 @@ (unless (sequence? g) (raise-type-error who "sequence" g))) sequences)) - (define (in-sequences sequence . sequences) - (let ([all (cons sequence sequences)]) - (check-sequences 'in-sequences all) - (if (null? sequences) sequence (append-sequences all #f)))) - (define (in-cycle sequence . sequences) - (let ([all (cons sequence sequences)]) - (check-sequences 'in-cycle all) - (append-sequences all #t))) + (define (in-sequences . sequences) + (check-sequences 'in-sequences sequences) + (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-parallel . sequences) (check-sequences 'in-parallel sequences) diff --git a/collects/scribblings/reference/sequences.scrbl b/collects/scribblings/reference/sequences.scrbl index 18abf2101f..baa2a2fa72 100644 --- a/collects/scribblings/reference/sequences.scrbl +++ b/collects/scribblings/reference/sequences.scrbl @@ -283,13 +283,20 @@ in the sequence. with @racket[0]. The elements of @racket[seq] must be single-valued.} @defproc[(in-sequences [seq sequence?] ...) sequence?]{ - Returns a sequence that is made of all input sequences, one after the - other. The elements of each @racket[seq] must all have the same - number of values.} + Returns a sequence that is made of all input sequences, one after + the other. Each @racket[seq] is @tech{initiate}d only after the + preceding @racket[seq] is exhausted. If a single @racket[seq] is + provided, then @racket[seq] is returned; otherwise, the elements of + each @racket[seq] must all have the same number of values.} @defproc[(in-cycle [seq sequence?] ...) sequence?]{ - Similar to @racket[in-sequences], but the sequences are repeated in an - infinite cycle.} + Similar to @racket[in-sequences], but the sequences are repeated in + an infinite cycle, where each @racket[seq] is @tech{initiate}d + afresh in each iteration. Beware that if no @racket[seq]s are + provided or if all @racket[seq]s become empty, then the sequence + produced by @racket[in-cycle] never returns when an element is + demanded---or even when the sequence is @tech{initiate}d, if all + @racket[seq]s are initially empty.} @defproc[(in-parallel [seq sequence?] ...) sequence?]{ Returns a sequence where each element has as many values as the number diff --git a/collects/tests/racket/for.rktl b/collects/tests/racket/for.rktl index 8d410676fb..691e309d5a 100644 --- a/collects/tests/racket/for.rktl +++ b/collects/tests/racket/for.rktl @@ -68,6 +68,10 @@ (test-sequence [(0 1 2 3 #\a #\b #\c) (10 11 12 13 #\A #\B #\C)] (in-sequences (in-parallel (in-range 0 4) (in-range 10 14)) (in-parallel "abc" "ABC"))) +;; Check empty sequences: +(test '() 'empty-seq (for/list ([v (in-sequences)]) v)) +(test '() 'empty-seq (for/list ([v (in-sequences '())]) v)) +(test '() 'empty-seq (for/list ([v (in-sequences '() '())]) v)) ;; use in-parallel to get a finite number of items (test-sequence [(0 1 2 3 0 1 2 3) (0 1 2 3 4 5 6 7)] @@ -76,6 +80,9 @@ (in-parallel (in-range 0 8) (in-cycle (in-range 0 3)))) (test-sequence [(0 1 2 3 2 1 0 1) (0 1 2 3 4 5 6 7)] (in-parallel (in-cycle (in-range 0 4) (in-range 2 0 -1)) (in-range 0 8))) +;; `in-cycle' accepts 0 arguments, but it never produces a value if asked: +(test #t sequence? (in-cycle)) +(test #t sequence? (in-cycle '())) (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))))