Skip to content

Commit

Permalink
racket/set: add set-first' and set-rest'
Browse files Browse the repository at this point in the history
  • Loading branch information
mflatt committed Sep 12, 2012
1 parent b8acee5 commit ac5965a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
23 changes: 21 additions & 2 deletions collects/racket/set.rkt
Expand Up @@ -3,12 +3,14 @@
racket/serialize
racket/pretty
racket/contract/base
racket/contract/combinator)
racket/contract/combinator
(only-in "private/for.rkt" prop:stream))

(provide set seteq seteqv
set? set-eq? set-eqv? set-equal?
set-empty? set-count
set-member? set-add set-remove
set-first set-rest
set-union set-intersect set-subtract set-symmetric-difference
subset? proper-subset?
set-map set-for-each
Expand Down Expand Up @@ -84,7 +86,10 @@
(=? (set-ht set1) (set-ht set2)))
(lambda (set hc) (add1 (hc (set-ht set))))
(lambda (set hc) (add1 (hc (set-ht set)))))
#:property prop:sequence (lambda (v) (*in-set v)))
#:property prop:sequence (lambda (v) (*in-set v))
#:property prop:stream (vector (lambda (s) (set-empty? s))
(lambda (s) (set-first s))
(lambda (s) (set-rest s))))

;; Not currently exporting this because I'm not sure whether this is the right semantics
;; for it yet, but it follows most closely the semantics of the old set/c implementation
Expand Down Expand Up @@ -265,6 +270,20 @@
(define (proper-subset? one two)
(subset* 'proper-subset? one two #t))

(define (set-first set)
(unless (set? set) (raise-argument-error 'set-first "set?" set))
(define ht (set-ht set))
(if (zero? (hash-count ht))
(raise-arguments-error 'set-first "given set is empty")
(hash-iterate-key ht (hash-iterate-first ht))))

(define (set-rest set)
(unless (set? set) (raise-argument-error 'set-rest "set?" set))
(define ht (set-ht set))
(if (zero? (hash-count ht))
(raise-arguments-error 'set-rest "given set is empty")
(make-set (hash-remove ht (hash-iterate-key ht (hash-iterate-first ht))))))

(define (set-map set proc)
(unless (set? set) (raise-argument-error 'set-map "set?" 0 set proc))
(unless (and (procedure? proc)
Expand Down
2 changes: 1 addition & 1 deletion collects/scribblings/reference/sequences.scrbl
Expand Up @@ -635,7 +635,7 @@ in the sequence.
@; ======================================================================
@section[#:tag "streams"]{Streams}

A @deftech{stream} is a kind of sequence that supports functional
A @deftech{stream} is a kind of @tech{sequence} that supports functional
iteration via @racket[stream-first] and @racket[stream-rest]. The
@racket[stream-cons] form constructs a lazy stream, but plain lists
can be used as stream, and functions such as @racket[in-range] and
Expand Down
18 changes: 15 additions & 3 deletions collects/scribblings/reference/sets.scrbl
Expand Up @@ -11,9 +11,10 @@ set, elements are equivalent via @racket[equal?], @racket[eqv?], or
element-comparison procedure (@racket[equal?], @racket[eqv?], or
@racket[eq?]) and have equivalent elements.

A set can be used as a single-valued sequence (see
@secref["sequences"]). The elements of the set serve as elements
of the sequence. See also @racket[in-set].
A set can be used as a @tech{stream} (see @secref["streams"]) and thus
as a single-valued @tech{sequence} (see @secref["sequences"]). The
elements of the set serve as elements of the stream or sequence. See
also @racket[in-set].

Operations on sets that contain elements that are mutated are
unpredictable in much the same way that @tech{hash table} operations are
Expand Down Expand Up @@ -50,6 +51,17 @@ Returns @racket[#t] if @racket[v] is in @racket[st], @racket[#f]
otherwise.}


@defproc[(set-first [st (and/c set? (not/c set-empty?))]) any/c]{

Produces an unspecified element of @racket[st]. Multiple uses of
@racket[set-first] on @racket[st] produce the same result.}


@defproc[(set-rest [st (and/c set? (not/c set-empty?))]) set?]{

Removes @racket[(set-first st)] from @racket[st].}


@defproc[(set-add [st set?] [v any/c]) set?]{

@margin-note{Like operations on immutable hash tables, ``constant
Expand Down
4 changes: 4 additions & 0 deletions collects/tests/racket/set.rktl
Expand Up @@ -34,6 +34,10 @@
(test #t set-member? (set 1 2 3) 3)
(test #f set-member? (set 1 2 3) 4)

(test #t stream? (set 1 2 3))
(test (set-first (set 1 2 3)) set-first (set 1 2 3))
(test (set-remove (set 1 2 3) (set-first (set 1 2 3))) set-rest (set 1 2 3))

(let ([s (set 1 2 3)])
(test #t equal? s (set-add (set-add (set-add (set) 1) 2) 3))
(test #t equal? (seteq 1 2 3) (seteq 1 2 3))
Expand Down
1 change: 1 addition & 0 deletions doc/release-notes/racket/HISTORY.txt
@@ -1,6 +1,7 @@
Version 5.3.0.24
Added PLTCOMPILEDROOTS and --compiled/-R command-line flag
Added `reroot-path'
racket/set: added set-first and set-rest, sets are streams

Version 5.3.0.23
Changed make-log-receiver to accept a logger name as an
Expand Down

0 comments on commit ac5965a

Please sign in to comment.