Rename seqn-*' to stream-*'.

Later this will grow, to include a few kinds of streams in a unified
way, and possibly change the sequence protocol to a point where these
functions are not causing such big runtime penalties.
This commit is contained in:
Eli Barzilay 2010-10-21 16:52:48 -04:00
parent 655b066a93
commit 2f5265854a
4 changed files with 180 additions and 175 deletions

View File

@ -1,7 +1,7 @@
(module sequence "pre-base.rkt"
(require "list.rkt")
(define empty-seqn
(define empty-stream
(make-do-sequence
(λ ()
(values
@ -12,10 +12,10 @@
(λ (val) #t)
(λ (pos val) #t)))))
(define (seqn->list s)
(define (stream->list s)
(for/list ([v s]) v))
(define-syntax-rule (-seqn-cons vs s)
(define-syntax-rule (-stream-cons vs s)
(make-do-sequence
(λ ()
(define-values (more? next) (sequence-generate s))
@ -30,31 +30,31 @@
(or (zero? pos) (more?)))
(λ _ #t)
(λ _ #t)))))
(define seqn-cons
(define stream-cons
(case-lambda
[()
(error 'seqn-cons "expects a sequence to extend, but received no arguments")]
(error 'stream-cons "expects a sequence to extend, but received no arguments")]
[(s)
(-seqn-cons (values) s)]
(-stream-cons (values) s)]
[(v s)
(-seqn-cons (values v) s)]
(-stream-cons (values v) s)]
[vs*s
; XXX double reverse is bad but moving split-at causes a problem I can't figure
(define s*vs (reverse vs*s))
(-seqn-cons (apply values (reverse (cdr s*vs))) (car s*vs))]))
(-stream-cons (apply values (reverse (cdr s*vs))) (car s*vs))]))
(define (seqn-first s)
(define (stream-first s)
(define-values (more? next) (sequence-generate s))
(unless (more?)
(error 'seqn-first "expects a sequence with at least one element"))
(error 'stream-first "expects a sequence with at least one element"))
(next))
(define (seqn-rest s)
(define (stream-rest s)
(make-do-sequence
(λ ()
(define-values (more? next) (sequence-generate s))
(unless (more?)
(error 'seqn-rest "expects a sequence with at least one element"))
(error 'stream-rest "expects a sequence with at least one element"))
(next)
(values
(λ (pos) (next))
@ -64,16 +64,16 @@
(λ _ #t)
(λ _ #t)))))
(define (seqn-length s)
(define (stream-length s)
(define-values (more? next) (sequence-generate s))
(let loop ([i 0])
(if (more?)
(begin (next) (loop (add1 i)))
i)))
(define (seqn-ref s i)
(define (stream-ref s i)
(unless (and (exact-integer? i) (i . >= . 0))
(error 'seqn-ref "expects an exact non-negative index, but got ~e" i))
(error 'stream-ref "expects an exact non-negative index, but got ~e" i))
(define-values (more? next) (sequence-generate s))
(let loop ([n i])
(cond
@ -83,18 +83,18 @@
(next)
(loop (sub1 n))]
[else
(error 'seqn-ref "expects a sequence with at least ~e element(s)" i)])))
(error 'stream-ref "expects a sequence with at least ~e element(s)" i)])))
(define (seqn-tail s i)
(define (stream-tail s i)
(unless (and (exact-integer? i) (i . >= . 0))
(error 'seqn-tail "expects an exact non-negative index, but got ~e" i))
(error 'stream-tail "expects an exact non-negative index, but got ~e" i))
(make-do-sequence
(λ ()
(define-values (more? next) (sequence-generate s))
(let loop ([n i])
(unless (zero? n)
(unless (more?)
(error 'seqn-tail "expects a sequence with at least ~e element(s)" i))
(error 'stream-tail "expects a sequence with at least ~e element(s)" i))
(next)
(loop (sub1 n))))
(values
@ -105,7 +105,7 @@
(λ _ #t)
(λ _ #t)))))
(define (-seqn-append s0 l)
(define (-stream-append s0 l)
(if (null? l)
s0
(make-do-sequence
@ -133,14 +133,14 @@
(λ _ #t)
(λ _ #t))))))
(define (seqn-append . l)
(define (stream-append . l)
(unless (andmap sequence? l)
(error 'seqn-append "expects only sequence arguments, given ~e" l))
(-seqn-append empty-seqn l))
(error 'stream-append "expects only sequence arguments, given ~e" l))
(-stream-append empty-stream l))
(define (seqn-map f s)
(define (stream-map f s)
(unless (procedure? f)
(error 'seqn-map "expects a procedure as the first argument, given ~e" f))
(error 'stream-map "expects a procedure as the first argument, given ~e" f))
(make-do-sequence
(λ ()
(define-values (more? next) (sequence-generate s))
@ -152,37 +152,37 @@
(λ _ #t)
(λ _ #t)))))
(define (seqn-andmap f s)
(define (stream-andmap f s)
(define-values (more? next) (sequence-generate s))
(let loop ()
(if (more?)
(and (call-with-values next f) (loop))
#t)))
(define (seqn-ormap f s)
(define (stream-ormap f s)
(define-values (more? next) (sequence-generate s))
(let loop ()
(if (more?)
(or (call-with-values next f) (loop))
#f)))
(define (seqn-for-each f s)
(define (stream-for-each f s)
(define-values (more? next) (sequence-generate s))
(let loop ()
(when (more?)
(call-with-values next f)
(loop))))
(define (seqn-fold f i s)
(define (stream-fold f i s)
(define-values (more? next) (sequence-generate s))
(let loop ([i i])
(if (more?)
(loop (call-with-values next (λ e (apply f i e))))
i)))
(define (seqn-filter f s)
(define (stream-filter f s)
(unless (procedure? f)
(error 'seqn-filter "expects a procedure as the first argument, given ~e" f))
(error 'stream-filter "expects a procedure as the first argument, given ~e" f))
(make-do-sequence
(λ ()
(define-values (more? next) (sequence-generate s))
@ -204,7 +204,7 @@
(λ _ #t)
(λ _ #t)))))
(define (seqn-add-between s e)
(define (stream-add-between s e)
(make-do-sequence
(λ ()
(define-values (more? next) (sequence-generate s))
@ -222,9 +222,9 @@
(λ _ #t)
(λ _ #t)))))
(define (seqn-count f s)
(define (stream-count f s)
(unless (procedure? f)
(error 'seqn-count "expects a procedure as the first argument, given ~e" f))
(error 'stream-count "expects a procedure as the first argument, given ~e" f))
(define-values (more? next) (sequence-generate s))
(let loop ([n 0])
(if (more?)
@ -233,20 +233,20 @@
(loop n))
n)))
(provide empty-seqn
seqn->list
seqn-cons
seqn-first
seqn-rest
seqn-length
seqn-ref
seqn-tail
seqn-append
seqn-map
seqn-andmap
seqn-ormap
seqn-for-each
seqn-fold
seqn-filter
seqn-add-between
seqn-count))
(provide empty-stream
stream->list
stream-cons
stream-first
stream-rest
stream-length
stream-ref
stream-tail
stream-append
stream-map
stream-andmap
stream-ormap
stream-for-each
stream-fold
stream-filter
stream-add-between
stream-count))

View File

@ -326,86 +326,86 @@ in the sequence.
@; ----------------------------------------------------------------------
@section{Additional Sequence Operations}
@defthing[empty-seqn sequence?]{
@defthing[empty-stream sequence?]{
A sequence with no elements.}
@defproc[(seqn->list [s sequence?]) list?]{
@defproc[(stream->list [s sequence?]) list?]{
Returns a list whose elements are the elements of the @scheme[s],
which must be a one-valued sequence. If @scheme[s] is infinite, this
function does not terminate.}
@defproc[(seqn-cons [v any/c]
...
[s sequence?])
@defproc[(stream-cons [v any/c]
...
[s sequence?])
sequence?]{
Returns a sequence whose first element is @scheme[(values v ...)] and whose
remaining elements are the same as @scheme[s].}
@defproc[(seqn-first [s sequence?])
@defproc[(stream-first [s sequence?])
(values any/c ...)]{
Returns the first element of @scheme[s].}
@defproc[(seqn-rest [s sequence?])
@defproc[(stream-rest [s sequence?])
sequence?]{
Returns a sequence equivalent to @scheme[s], except the first element
is omitted.}
@defproc[(seqn-length [s sequence?])
@defproc[(stream-length [s sequence?])
exact-nonnegative-integer?]{
Returns the number of elements of @scheme[s]. If @scheme[s] is
infinite, this function does not terminate.}
@defproc[(seqn-ref [s sequence?] [i exact-nonnegative-integer?])
@defproc[(stream-ref [s sequence?] [i exact-nonnegative-integer?])
(values any/c ...)]{
Returns the @scheme[i]th element of @scheme[s].}
@defproc[(seqn-tail [s sequence?] [i exact-nonnegative-integer?])
@defproc[(stream-tail [s sequence?] [i exact-nonnegative-integer?])
sequence?]{
Returns a sequence equivalent to @scheme[s], except the first
@scheme[i] elements are omitted.}
@defproc[(seqn-append [s sequence?] ...)
@defproc[(stream-append [s sequence?] ...)
sequence?]{
Returns a sequence that contains all elements of each sequence in the
order they appear in the original sequences. The new sequence is
constructed lazily.}
@defproc[(seqn-map [f procedure?]
[s sequence?])
@defproc[(stream-map [f procedure?]
[s sequence?])
sequence?]{
Returns a sequence that contains @scheme[f] applied to each element of
@scheme[s]. The new sequence is constructed lazily.}
@defproc[(seqn-andmap [f (-> any/c ... boolean?)]
[s sequence?])
@defproc[(stream-andmap [f (-> any/c ... boolean?)]
[s sequence?])
boolean?]{
Returns @scheme[#t] if @scheme[f] returns a true result on every
element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never
returns a false result, this function does not terminate.}
@defproc[(seqn-ormap [f (-> any/c ... boolean?)]
[s sequence?])
@defproc[(stream-ormap [f (-> any/c ... boolean?)]
[s sequence?])
boolean?]{
Returns @scheme[#t] if @scheme[f] returns a true result on some
element of @scheme[s]. If @scheme[s] is infinite and @scheme[f] never
returns a true result, this function does not terminate.}
@defproc[(seqn-for-each [f (-> any/c ... any)]
[s sequence?])
@defproc[(stream-for-each [f (-> any/c ... any)]
[s sequence?])
(void)]{
Applies @scheme[f] to each element of @scheme[s]. If @scheme[s] is
infinite, this function does not terminate.}
@defproc[(seqn-fold [f (-> any/c any/c ... any/c)]
[i any/c]
[s sequence?])
@defproc[(stream-fold [f (-> any/c any/c ... any/c)]
[i any/c]
[s sequence?])
(void)]{
Folds @scheme[f] over each element of @scheme[s] with @scheme[i] as
the initial accumulator. If @scheme[s] is infinite, this function
does not terminate.}
@defproc[(seqn-filter [f (-> any/c ... boolean?)]
[s sequence?])
@defproc[(stream-filter [f (-> any/c ... boolean?)]
[s sequence?])
sequence?]{
Returns a sequence whose elements are the elements of @scheme[s] for
which @scheme[f] returns a true result. Although the new sequence is
@ -414,13 +414,13 @@ in the sequence.
@scheme[f] returns a true result then operations on this sequence will
not terminate during that infinite sub-sequence.}
@defproc[(seqn-add-between [s sequence?] [e any/c])
@defproc[(stream-add-between [s sequence?] [e any/c])
sequence?]{
Returns a sequence whose elements are the elements of @scheme[s]
except in between each is @scheme[e]. The new sequence is constructed
lazily.}
@defproc[(seqn-count [f procedure?] [s sequence?])
@defproc[(stream-count [f procedure?] [s sequence?])
exact-nonnegative-integer?]{
Returns the number of elements in @scheme[s] for which @scheme[f]
returns a true result. If @scheme[s] is infinite, this function does

View File

@ -352,105 +352,110 @@
;; New operators
(require racket/private/sequence)
(test '(0 1 2) 'seqn->list (seqn->list (in-range 3)))
(arity-test seqn->list 1 1)
(err/rt-test (seqn->list 1))
(test '(0 1 2) 'stream->list (stream->list (in-range 3)))
(arity-test stream->list 1 1)
(err/rt-test (stream->list 1))
(test '() 'empty-seqn (seqn->list empty-seqn))
(test '() 'empty-stream (stream->list empty-stream))
; XXX How do I check rest arity?
(test '(0 1 2) 'seqn-cons (seqn->list (seqn-cons 0 (in-range 1 3))))
(test '((0 1)) 'seqn-cons
(for/list ([(a b) (seqn-cons 0 1 empty-seqn)])
(test '(0 1 2) 'stream-cons (stream->list (stream-cons 0 (in-range 1 3))))
(test '((0 1)) 'stream-cons
(for/list ([(a b) (stream-cons 0 1 empty-stream)])
(list a b)))
(arity-test seqn-first 1 1)
(err/rt-test (seqn-first 1))
(test 0 'seqn-first (seqn-first (in-naturals)))
(arity-test stream-first 1 1)
(err/rt-test (stream-first 1))
(test 0 'stream-first (stream-first (in-naturals)))
(test #t
'seqn-first
'stream-first
(equal? (list 0 1)
(call-with-values
(λ ()
(seqn-first (seqn-cons 0 1 empty-seqn)))
(stream-first (stream-cons 0 1 empty-stream)))
(λ args args))))
(arity-test seqn-rest 1 1)
(test '(1 2) 'seqn-rest (seqn->list (seqn-rest (in-range 3))))
(arity-test stream-rest 1 1)
(test '(1 2) 'stream-rest (stream->list (stream-rest (in-range 3))))
(arity-test seqn-length 1 1)
(err/rt-test (seqn-length 1))
(test 3 'seqn-length (seqn-length (in-range 3)))
(test 3 'seqn-length (seqn-length #hasheq((1 . 'a) (2 . 'b) (3 . 'c))))
(arity-test stream-length 1 1)
(err/rt-test (stream-length 1))
(test 3 'stream-length (stream-length (in-range 3)))
(test 3 'stream-length (stream-length #hasheq((1 . 'a) (2 . 'b) (3 . 'c))))
(arity-test seqn-ref 2 2)
(err/rt-test (seqn-ref 2 0))
(err/rt-test (seqn-ref (in-naturals) -1) exn:fail?)
(err/rt-test (seqn-ref (in-naturals) 1.0) exn:fail?)
(test 0 'seqn-ref (seqn-ref (in-naturals) 0))
(test 1 'seqn-ref (seqn-ref (in-naturals) 1))
(test 25 'seqn-ref (seqn-ref (in-naturals) 25))
(arity-test stream-ref 2 2)
(err/rt-test (stream-ref 2 0))
(err/rt-test (stream-ref (in-naturals) -1) exn:fail?)
(err/rt-test (stream-ref (in-naturals) 1.0) exn:fail?)
(test 0 'stream-ref (stream-ref (in-naturals) 0))
(test 1 'stream-ref (stream-ref (in-naturals) 1))
(test 25 'stream-ref (stream-ref (in-naturals) 25))
(arity-test seqn-tail 2 2)
(err/rt-test (seqn-tail (in-naturals) -1) exn:fail?)
(err/rt-test (seqn-tail (in-naturals) 1.0) exn:fail?)
(test 4 'seqn-ref (seqn-ref (seqn-tail (in-naturals) 4) 0))
(test 5 'seqn-ref (seqn-ref (seqn-tail (in-naturals) 4) 1))
(test 29 'seqn-ref (seqn-ref (seqn-tail (in-naturals) 4) 25))
(arity-test stream-tail 2 2)
(err/rt-test (stream-tail (in-naturals) -1) exn:fail?)
(err/rt-test (stream-tail (in-naturals) 1.0) exn:fail?)
(test 4 'stream-ref (stream-ref (stream-tail (in-naturals) 4) 0))
(test 5 'stream-ref (stream-ref (stream-tail (in-naturals) 4) 1))
(test 29 'stream-ref (stream-ref (stream-tail (in-naturals) 4) 25))
; XXX Check for rest
(err/rt-test (seqn-append 1) exn:fail?)
(err/rt-test (seqn-append (in-naturals) 1) exn:fail?)
(test '() 'seqn-append (seqn->list (seqn-append)))
(test 5 'seqn-append (seqn-ref (seqn-append (in-naturals)) 5))
(test 5 'seqn-append (seqn-ref (seqn-append (in-range 3) (in-range 3 10)) 5))
(err/rt-test (stream-append 1) exn:fail?)
(err/rt-test (stream-append (in-naturals) 1) exn:fail?)
(test '() 'stream-append (stream->list (stream-append)))
(test 5 'stream-append (stream-ref (stream-append (in-naturals)) 5))
(test 5 'stream-append
(stream-ref (stream-append (in-range 3) (in-range 3 10)) 5))
(arity-test seqn-map 2 2)
(err/rt-test (seqn-map 2 (in-naturals)) exn:fail?)
(test '(1 2 3) 'seqn-map (seqn->list (seqn-map add1 (in-range 3))))
(test 3 'seqn-map (seqn-ref (seqn-map add1 (in-naturals)) 2))
(arity-test stream-map 2 2)
(err/rt-test (stream-map 2 (in-naturals)) exn:fail?)
(test '(1 2 3) 'stream-map (stream->list (stream-map add1 (in-range 3))))
(test 3 'stream-map (stream-ref (stream-map add1 (in-naturals)) 2))
(arity-test seqn-andmap 2 2)
(err/rt-test (seqn-andmap 2 (in-naturals)))
(test #t 'seqn-andmap (seqn-andmap even? (seqn-cons 2 empty-seqn)))
(test #f 'seqn-andmap (seqn-andmap even? (in-naturals)))
(arity-test stream-andmap 2 2)
(err/rt-test (stream-andmap 2 (in-naturals)))
(test #t 'stream-andmap (stream-andmap even? (stream-cons 2 empty-stream)))
(test #f 'stream-andmap (stream-andmap even? (in-naturals)))
(arity-test seqn-ormap 2 2)
(err/rt-test (seqn-ormap 2 (in-naturals)))
(test #t 'seqn-ormap (seqn-ormap even? (seqn-cons 2 empty-seqn)))
(test #f 'seqn-ormap (seqn-ormap even? (seqn-cons 1 empty-seqn)))
(test #t 'seqn-ormap (seqn-ormap even? (in-naturals)))
(arity-test stream-ormap 2 2)
(err/rt-test (stream-ormap 2 (in-naturals)))
(test #t 'stream-ormap (stream-ormap even? (stream-cons 2 empty-stream)))
(test #f 'stream-ormap (stream-ormap even? (stream-cons 1 empty-stream)))
(test #t 'stream-ormap (stream-ormap even? (in-naturals)))
(arity-test seqn-for-each 2 2)
(err/rt-test (seqn-for-each 2 (in-naturals)))
(arity-test stream-for-each 2 2)
(err/rt-test (stream-for-each 2 (in-naturals)))
(test (vector 0 1 2)
'seqn-for-each
'stream-for-each
(let ([v (vector #f #f #f)])
(seqn-for-each (λ (i) (vector-set! v i i)) (in-range 3))
(stream-for-each (λ (i) (vector-set! v i i)) (in-range 3))
v))
(arity-test seqn-fold 3 3)
(err/rt-test (seqn-fold 2 (in-naturals) 0))
(test 6 'seqn-fold (seqn-fold + 0 (in-range 4)))
(arity-test stream-fold 3 3)
(err/rt-test (stream-fold 2 (in-naturals) 0))
(test 6 'stream-fold (stream-fold + 0 (in-range 4)))
(arity-test seqn-filter 2 2)
(err/rt-test (seqn-filter 2 (in-naturals)) exn:fail?)
(test 4 'seqn-filter (seqn-ref (seqn-filter even? (in-naturals)) 2))
(arity-test stream-filter 2 2)
(err/rt-test (stream-filter 2 (in-naturals)) exn:fail?)
(test 4 'stream-filter (stream-ref (stream-filter even? (in-naturals)) 2))
(arity-test seqn-add-between 2 2)
(test 0 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 0))
(test #t 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 1))
(test 1 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 2))
(test #t 'seqn-add-between (seqn-ref (seqn-add-between (in-naturals) #t) 3))
(arity-test stream-add-between 2 2)
(test 0 'stream-add-between
(stream-ref (stream-add-between (in-naturals) #t) 0))
(test #t 'stream-add-between
(stream-ref (stream-add-between (in-naturals) #t) 1))
(test 1 'stream-add-between
(stream-ref (stream-add-between (in-naturals) #t) 2))
(test #t 'stream-add-between
(stream-ref (stream-add-between (in-naturals) #t) 3))
(arity-test seqn-count 2 2)
(test 0 'seqn-count (seqn-count even? empty-seqn))
(test 1 'seqn-count (seqn-count even? (in-range 1)))
(test 5 'seqn-count (seqn-count even? (in-range 10)))
(arity-test stream-count 2 2)
(test 0 'stream-count (stream-count even? empty-stream))
(test 1 'stream-count (stream-count even? (in-range 1)))
(test 5 'stream-count (stream-count even? (in-range 10)))
(let* ([r (random 100)]
[a (if (even? r)
(/ r 2)
(ceiling (/ r 2)))])
(test a 'seqn-count (seqn-count even? (in-range r))))
(test a 'stream-count (stream-count even? (in-range r))))
(report-errs)

View File

@ -1,12 +1,13 @@
#lang racket
(require tests/stress)
; seqn-first
; This ignores the greater flexiblity of seqn-first to have more than single-valued sequences
;; stream-first
;; This ignores the greater flexiblity of stream-first to have more than
;; single-valued sequences
(stress
200
["seqn-first"
(seqn-first (in-naturals))]
["stream-first"
(stream-first (in-naturals))]
["for/or (val)"
(define s (in-naturals))
(for/or ([n s])
@ -15,12 +16,12 @@
(for/or ([n (in-naturals)])
n)])
; seqn-length
; The for/fold must be rewritten slightly differently for multi-valued
;; stream-length
;; The for/fold must be rewritten slightly differently for multi-valued
(stress
20
["seqn-length"
(seqn-length (in-range 2000))]
["stream-length"
(stream-length (in-range 2000))]
["for/fold (val)"
(define s (in-range 2000))
(for/fold ([len 0])
@ -31,12 +32,12 @@
([i (in-range 2000)])
(add1 len))])
; seqn-ref
; Ditto
;; stream-ref
;; Ditto
(stress
20
["seqn-ref"
(seqn-ref (in-range 2000) 200)]
["stream-ref"
(stream-ref (in-range 2000) 200)]
["for/or val"
(define s (in-range 2000))
(for/or ([e s]
@ -49,12 +50,12 @@
#:when (i . = . 199))
e)])
; seqn-andmap
; ditto
;; stream-andmap
;; ditto
(stress
20
["seqn-andmap"
(seqn-andmap number? (in-range 2000))]
["stream-andmap"
(stream-andmap number? (in-range 2000))]
["for/and val"
(define s (in-range 2000))
(for/and ([e s])
@ -63,12 +64,12 @@
(for/and ([e (in-range 2000)])
(number? e))])
; seqn-ormap
; ditto
;; stream-ormap
;; ditto
(stress
20
["seqn-ormap"
(seqn-ormap string? (in-range 2000))]
["stream-ormap"
(stream-ormap string? (in-range 2000))]
["for/and val"
(define s (in-range 2000))
(for/or ([e s])
@ -77,12 +78,12 @@
(for/or ([e (in-range 2000)])
(string? e))])
; seqn-fold
; The for/fold must be rewritten slightly differently for multi-valued
;; stream-fold
;; The for/fold must be rewritten slightly differently for multi-valued
(stress
20
["seqn-fold"
(seqn-fold + 0 (in-range 2000))]
["stream-fold"
(stream-fold + 0 (in-range 2000))]
["for/fold (val)"
(define s (in-range 2000))
(for/fold ([sum 0])
@ -93,12 +94,12 @@
([i (in-range 2000)])
(+ i sum))])
; seqn-count
; The for/fold must be rewritten slightly differently for multi-valued
;; stream-count
;; The for/fold must be rewritten slightly differently for multi-valued
(stress
20
["seqn-count"
(seqn-count even? (in-range 2000))]
["stream-count"
(stream-count even? (in-range 2000))]
["for/fold (val)"
(define s (in-range 2000))
(for/fold ([num 0])
@ -110,4 +111,3 @@
([i (in-range 2000)]
#:when (even? i))
(add1 num))])