support exact nonnegative integers as sequences

This commit is contained in:
Matthew Flatt 2011-04-18 14:54:42 -06:00
parent 4e576a8ac9
commit e0d26d88b6
7 changed files with 44 additions and 10 deletions

View File

@ -424,7 +424,8 @@
v)))
(define (sequence? v)
(or (do-sequence? v)
(or (exact-nonnegative-integer? v)
(do-sequence? v)
(sequence-via-prop? v)
(stream? v)
(mpair? v)
@ -437,6 +438,7 @@
(define (make-sequence who v)
(cond
[(exact-nonnegative-integer? v) (:integer-gen v)]
[(do-sequence? v) ((do-sequence-ref v 0))]
[(mpair? v) (:mlist-gen v)]
[(list? v) (:list-gen v)]
@ -498,6 +500,9 @@
[inc (lambda (x) (+ x step))])
(make-range a inc cont?))]))
(define (:integer-gen v)
(values values add1 0 (lambda (i) (i . < . v)) #f #f))
(define in-naturals
(case-lambda
[() (in-naturals 0)]

View File

@ -59,6 +59,7 @@
(cond
[(zero? i) seq]
[(stream? seq) (stream-tail seq i)]
[(exact-nonnegative-integer? seq) (stream-tail (in-range seq) i)]
[else
(make-do-sequence
(lambda ()

View File

@ -29,6 +29,8 @@ the @racket[_body]s for side effects.
(display i))
(for ([i "abc"])
(printf "~a..." i))
(for ([i 4])
(display i))
]
The @racket[for/list] variant of @racket[for] is more Racket-like. It
@ -42,6 +44,8 @@ comprehension}.
(* i i))
(for/list ([i "abc"])
i)
(for/list ([i 4])
i)
]
The full syntax of @racket[for] accommodates multiple sequences to
@ -59,9 +63,12 @@ see the kinds of sequence generators that make interesting examples.
The @racket[in-range] function generates a sequence of numbers, given
an optional starting number (which defaults to @racket[0]), a number
before which the sequences ends, and an optional step (which defaults
to @racket[1]).
to @racket[1]). Using a non-negative integer @racket[_k] directly as
a sequence is a shorthand for @racket[(in-range _k)].
@examples[
(for ([i 3])
(display i))
(for ([i (in-range 3)])
(display i))
(for ([i (in-range 1 4)])
@ -102,7 +109,8 @@ true.
Sequence constructors like @racket[in-list], @racket[in-vector] and
@racket[in-string] simply make explicit the use of a list, vector, or
string as a sequence. Since they raise an exception when given the
string as a sequence. Along with @racket[in-range],
these constructors raise an exception when given the
wrong kind of value, and since they otherwise avoid a run-time
dispatch to determine the sequence type, they enable more efficient
code generation; see @secref["for-performance"] for more information.
@ -425,7 +433,8 @@ fast-clause [id fast-seq]
@racketgrammar[
#:literals [in-range in-naturals in-list in-vector in-string in-bytes in-value stop-before stop-after]
fast-seq (in-range expr expr)
fast-seq (in-range expr)
(in-range expr expr)
(in-range expr expr expr)
(in-naturals)
(in-naturals expr)

View File

@ -35,6 +35,8 @@ built-in datatypes, the sequence datatype includes the following:
@itemize[
@item{exact nonnegative integers (see below)}
@item{strings (see @secref["strings"])}
@item{byte strings (see @secref["bytestrings"])}
@ -57,6 +59,10 @@ built-in datatypes, the sequence datatype includes the following:
]
An @tech{exact number} @racket[_k] that is a non-negative
@tech{integer} acts as a sequence similar to @racket[(in-range _k)],
except that @racket[_k] by itself is not a @tech{stream}.
The @scheme[make-do-sequence] function creates a sequence given a
thunk that returns procedures to implement a sequence, and the
@scheme[prop:sequence] property can be associated with a structure

View File

@ -6,9 +6,13 @@
(require racket/mpair
"for-util.rkt")
(test-sequence [(0 1 2)] 3)
(test-sequence [(0 1 2)] (in-range 3))
(test-sequence [(3 4 5)] (in-range 3 6))
(test-sequence [(7 6 5)] (in-range 7 4 -1))
(test-sequence [(3.0 4.0 5.0)] (in-range 3.0 6.0))
(test-sequence [(3.0 3.5 4.0 4.5 5.0 5.5)] (in-range 3.0 6.0 0.5))
(test-sequence [(3.0 3.1 3.2)] (in-range 3.0 3.3 0.1))
(test-sequence [(a b c)] '(a b c))
(test-sequence [(a b c)] (in-list '(a b c)))
@ -228,7 +232,7 @@
(test 13 next)
(test #f more?))
;; check ranges on `in-vetcor', especially as a value
;; check ranges on `in-vector', especially as a value
(test '() 'in-empty-vector (let ([v (in-vector '#())]) (for/list ([e v]) e)))
(test '() 'in-empty-vector (let ([v (in-vector '#() 0)]) (for/list ([e v]) e)))
(test '() 'in-empty-vector (let ([v (in-vector '#() 0 0)]) (for/list ([e v]) e)))

View File

@ -29,21 +29,23 @@
(test '(0 1 2) 'sequence->list (sequence->list (in-range 3)))
(arity-test sequence->list 1 1)
(err/rt-test (sequence->list 1))
(err/rt-test (sequence->list 'a))
(test '() 'empty-sequence (sequence->list empty-sequence))
(arity-test sequence-length 1 1)
(err/rt-test (sequence-length 1))
(err/rt-test (sequence-length 'a))
(test 3 'sequence-length (sequence-length (in-range 3)))
(arity-test sequence-ref 2 2)
(err/rt-test (sequence-ref 2 0))
(err/rt-test (sequence-ref 'a 0))
(err/rt-test (sequence-ref (in-naturals) -1) exn:fail?)
(err/rt-test (sequence-ref (in-naturals) 1.0) exn:fail?)
(test 0 'sequence-ref (sequence-ref (in-naturals) 0))
(test 1 'sequence-ref (sequence-ref (in-naturals) 1))
(test 25 'sequence-ref (sequence-ref (in-naturals) 25))
(when (sequence? 10)
(test 3 sequence-ref 10 3))
(arity-test sequence-tail 2 2)
(err/rt-test (sequence-tail (in-naturals) -1) exn:fail?)
@ -51,14 +53,18 @@
(test 4 'sequence-ref (sequence-ref (sequence-tail (in-naturals) 4) 0))
(test 5 'sequence-ref (sequence-ref (sequence-tail (in-naturals) 4) 1))
(test 29 'sequence-ref (sequence-ref (sequence-tail (in-naturals) 4) 25))
(when (sequence? 10)
(test 29 'sequence-ref (sequence-ref (sequence-tail 100 4) 25)))
;; XXX Check for rest
(err/rt-test (sequence-append 1) exn:fail?)
(err/rt-test (sequence-append (in-naturals) 1) exn:fail?)
(err/rt-test (sequence-append 'a) exn:fail?)
(err/rt-test (sequence-append (in-naturals) 'a) exn:fail?)
(test '() 'sequence-append (sequence->list (sequence-append)))
(test 5 'sequence-append (sequence-ref (sequence-append (in-naturals)) 5))
(test 5 'sequence-append
(sequence-ref (sequence-append (in-range 3) (in-range 3 10)) 5))
(when (sequence? 10)
(test 5 sequence-ref (sequence-append 4 10) 9))
(arity-test sequence-map 2 2)
(err/rt-test (sequence-map 2 (in-naturals)) exn:fail?)

View File

@ -1,3 +1,6 @@
Version 5.1.1.2
Changed "sequence" to include exact nonnegative integers
Version 5.1.1, May 2011
Enabled single-precision floats by default
Added single-flonum?