I'd like comments on this addition in response to the blog post we saw on the list today.
Jay On Wed, Aug 11, 2010 at 5:40 PM, <j...@racket-lang.org> wrote: > jay has updated `master' from 8dc38e9d84 to e06f0e78b2. > http://git.racket-lang.org/plt/8dc38e9d84..e06f0e78b2 > > =====[ 4 Commits ]====================================================== > > Directory summary: > 17.8% collects/racket/private/ > 29.6% collects/scribblings/reference/ > 20.9% collects/tests/racket/ > 9.4% collects/tests/unstable/ > 18.9% collects/unstable/scribblings/ > 3.2% collects/unstable/ > > ~~~~~~~~~~ > > db87add Jay McCarthy <j...@racket-lang.org> 2010-08-11 16:37 > : > | Adding hash-domain and hash-range to racket/base > : > M collects/racket/private/base.rkt | 4 +++- > A collects/racket/private/hash.rkt > M collects/scribblings/reference/hashes.scrbl | 11 +++++++++++ > M collects/tests/racket/basic.rktl | 5 +++++ > M collects/unstable/hash.rkt | 8 -------- > > ~~~~~~~~~~ > > 58ad011 Jay McCarthy <j...@racket-lang.org> 2010-08-11 16:42 > : > | Adding hash->list > : > M collects/racket/private/hash.rkt | 11 +++-- > M collects/scribblings/reference/hashes.scrbl | 6 +++ > M collects/tests/racket/basic.rktl | 1 + > M collects/tests/unstable/hash.rkt | 12 ------ > M collects/unstable/scribblings/hash.scrbl | 51 ------------------------ > > ~~~~~~~~~~ > > fadfee7 Jay McCarthy <j...@racket-lang.org> 2010-08-11 16:49 > : > | Normalizing docs a little > : > M collects/scribblings/reference/hashes.scrbl | 9 ++++++--- > > ~~~~~~~~~~ > > e06f0e7 Jay McCarthy <j...@racket-lang.org> 2010-08-11 17:39 > : > | Adding hash-set* and hash-set*bang > : > M collects/racket/private/hash.rkt | 22 ++++++++++++++- > M collects/scribblings/reference/hashes.scrbl | 26 +++++++++++++++++ > M collects/tests/racket/basic.rktl | 36 ++++++++++++++++++++++-- > > =====[ Overall Diff ]=================================================== > > collects/racket/private/base.rkt > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/racket/private/base.rkt > +++ NEW/collects/racket/private/base.rkt > @@ -1,6 +1,7 @@ > (module base "pre-base.rkt" > > - (#%require "list.rkt" > + (#%require "hash.rkt" > + "list.rkt" > "string.rkt" > "stxcase-scheme.rkt" > "qqstx.rkt" > @@ -21,6 +22,7 @@ > regexp-replace* > new-apply-proc) > struct > + (all-from "hash.rkt") > (all-from "list.rkt") > (all-from-except "string.rkt" > -regexp-replace*) > > collects/racket/private/hash.rkt > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- /dev/null > +++ NEW/collects/racket/private/hash.rkt > @@ -0,0 +1,33 @@ > +(module hash "pre-base.rkt" > + (define (hash-domain table) > + (hash-map table (λ (k v) k))) > + > + (define (hash-range table) > + (hash-map table (λ (k v) v))) > + > + (define (hash->list table) > + (hash-map table cons)) > + > + (define (hash-set* table . pairs) > + (unless (even? (length pairs)) > + (error 'hash-set* "expected an even number of association elements, > but received an odd number: ~e" pairs)) > + (let loop ([table table] > + [pairs pairs]) > + (if (null? pairs) > + table > + (loop (hash-set table (car pairs) (cadr pairs)) > + (cddr pairs))))) > + > + (define (hash-set*! table . pairs) > + (unless (even? (length pairs)) > + (error 'hash-set*! "expected an even number of association elements, > but received an odd number: ~e" pairs)) > + (let loop ([pairs pairs]) > + (unless (null? pairs) > + (hash-set! table (car pairs) (cadr pairs)) > + (loop (cddr pairs))))) > + > + (provide hash-domain > + hash-range > + hash->list > + hash-set* > + hash-set*!)) > \ No newline at end of file > > collects/scribblings/reference/hashes.scrbl > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/scribblings/reference/hashes.scrbl > +++ NEW/collects/scribblings/reference/hashes.scrbl > @@ -180,6 +180,18 @@ Maps @scheme[key] to @scheme[v] in @scheme[hash], > overwriting > any existing mapping for @scheme[key]. > > �...@see-also-caveats[]} > + > +...@defproc[(hash-set*! [hash (and/c hash? (not/c immutable?))] > + [key any/c] > + [v any/c] > + ... > + ...) void?]{ > + > +Maps each @scheme[key] to each @scheme[v] in @scheme[hash], overwriting > +any existing mapping for each @scheme[key]. Mappings are added from the > left, so > +later mappings overwrite earlier mappings. > + > +...@see-also-caveats[]} > > > �...@defproc[(hash-set [hash (and/c hash? immutable?)] > @@ -192,6 +204,20 @@ Functionally extends @scheme[hash] by mapping > @scheme[key] to > returning the extended hash table. > > �...@see-also-mutable-key-caveat[]} > + > +...@defproc[(hash-set* [hash (and/c hash? immutable?)] > + [key any/c] > + [v any/c] > + ... > + ...) > + (and/c hash? immutable?)]{ > + > +Functionally extends @scheme[hash] by mapping each @scheme[key] to > +...@scheme[v], overwriting any existing mapping for each @scheme[key], and > +returning the extended hash table. Mappings are added from the left, so > +later mappings overwrite earlier mappings. > + > +...@see-also-mutable-key-caveat[]} > > �...@defproc[(hash-ref [hash hash?] > [key any/c] > @@ -303,7 +329,27 @@ otherwise the traversal skips a deleted key or uses the > remapped key's > new value. > > �...@see-also-concurrency-caveat[]} > + > +...@defproc[(hash-domain [hash hash?]) > + (listof any/c)]{ > +Returns a list of the keys of @scheme[hash] in an unspecified order. > + > +See @scheme[hash-map] for information about modifying @scheme[hash] > +during @scheme[hash-domain]. @see-also-concurrency-caveat[]} > > +...@defproc[(hash-range [hash hash?]) > + (listof any/c)]{ > +Returns a list of the values of @scheme[hash] in an unspecified order. > + > +See @scheme[hash-map] for information about modifying @scheme[hash] > +during @scheme[hash-range]. @see-also-concurrency-caveat[]} > + > +...@defproc[(hash->list [hash hash?]) > + (listof (cons/c any/c any/c))]{ > +Returns a list of the key--value pairs of @scheme[hash] in an unspecified > order. > + > +See @scheme[hash-map] for information about modifying @scheme[hash] > +during @scheme[hash->list]. @see-also-concurrency-caveat[]} > > �...@defproc[(hash-for-each [hash hash?] > [proc (any/c any/c . -> . any)]) > > collects/tests/racket/basic.rktl > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/tests/racket/basic.rktl > +++ NEW/collects/tests/racket/basic.rktl > @@ -2363,8 +2363,44 @@ > (check-all-bad hash-iterate-key) > (check-all-bad hash-iterate-value)) > > +(test (list 1 2 3) hash-domain #hasheq((1 . a)(2 . b)(3 . c))) > +(test (list 'a 'b 'c) hash-range #hasheq((1 . a)(2 . b)(3 . c))) > +(test (list (cons 1 'a) (cons 2 'b) (cons 3 'c)) hash->list #hasheq((1 . > a)(2 . b)(3 . c))) > + > +(err/rt-test (hash-set*! im-t 1 2) exn:fail?) > +(err/rt-test (hash-set* (make-hasheq null) 1 2) exn:fail?) > +(err/rt-test (hash-set* im-t 1 2 3) exn:fail?) > +(err/rt-test (hash-set*! (make-hasheq null) 1 2 3) exn:fail?) > + > +(test #t equal? (hash-set* (hasheq 1 'a 3 'b)) (hasheq 1 'a 3 'b)) > +(test #t equal? (hasheq 1 2 3 4) > + (hash-set* (hasheq 1 'a 3 'b) > + 1 (gensym) > + 1 2 > + 3 (gensym) > + 3 4)) > +(test #t equal? (make-hasheq (list (cons 1 'a) (cons 3 'b))) > + (let ([ht (make-hasheq (list (cons 1 'a) (cons 3 'b)))]) > + (hash-set*! ht) > + ht)) > +(test #t equal? (make-hasheq (list (cons 1 2) (cons 3 'b))) > + (let ([ht (make-hasheq (list (cons 1 'a) (cons 3 'b)))]) > + (hash-set*! ht > + 1 2) > + ht)) > +(test #t equal? (make-hasheq (list (cons 1 2) (cons 3 4))) > + (let ([ht (make-hasheq (list (cons 1 'a) (cons 3 'b)))]) > + (hash-set*! ht > + 1 (gensym) > + 1 2 > + 3 (gensym) > + 3 4) > + ht)) > + > (arity-test make-immutable-hash 1 1) > (arity-test make-immutable-hasheq 1 1) > +(arity-test hash-domain 1 1) > +(arity-test hash-range 1 1) > (arity-test hash-count 1 1) > (arity-test hash-ref 2 3) > (arity-test hash-set! 3 3) > > collects/tests/unstable/hash.rkt > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/tests/unstable/hash.rkt > +++ NEW/collects/tests/unstable/hash.rkt > @@ -4,10 +4,6 @@ > > (run-tests > (test-suite "hash.ss" > - (test-suite "hash-equal?" > - (test (check-true (hash-equal? #hash()))) > - (test (check-false (hash-equal? #hasheq()))) > - (test (check-false (hash-equal? #hasheqv())))) > (test-suite "hash-ref/check" > (test-ok (check-equal? (hash-ref/check #hash([1 . one] [2 . two]) 1) > 'one)) > @@ -31,14 +27,6 @@ > (check-equal? (hash-ref/failure #hash([1 . one] [2 . two]) 3 f) > 8) > (check-equal? x 8))) > - (test-suite "hash-has-key?" > - (test-ok (check-equal? (hash-has-key? #hash([1 . one] [2 . two]) 1) #t)) > - (test-ok (check-equal? (hash-has-key? #hash([1 . one] [2 . two]) 3) > #f))) > - (test-suite "hash-domain" > - (test-ok (check-equal? (hash-domain #hash([1 . one] [2 . two])) '(1 > 2)))) > - (test-suite "hash-range" > - (test-ok (check-equal? (hash-range #hash([1 . one] [2 . two])) > - '(one two)))) > (test-suite "hash-union" > (test-ok (hash-union #hash([1 . one] [2 . two]) > #hash([3 . three] [4 . four])) > > collects/unstable/hash.rkt > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/unstable/hash.rkt > +++ NEW/collects/unstable/hash.rkt > @@ -14,12 +14,6 @@ > (define (hash-ref/failure table key failure) > (hash-ref table key (lambda () (failure)))) > > -(define (hash-domain table) > - (for/list ([i (in-hash-keys table)]) i)) > - > -(define (hash-range table) > - (for/list ([i (in-hash-values table)]) i)) > - > (define ((hash-duplicate-error name) key value1 value2) > (error name "duplicate values for key ~e: ~e and ~e" key value1 value2)) > > @@ -55,8 +49,6 @@ > (->d ([table hash?] [key any/c]) () > #:pre-cond (hash-has-key? table key) > [_ any/c])] > - [hash-domain (-> hash? list?)] > - [hash-range (-> hash? list?)] > [hash-union (->* [(and/c hash? immutable?)] > [#:combine > (-> any/c any/c any/c) > > collects/unstable/scribblings/hash.scrbl > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/unstable/scribblings/hash.scrbl > +++ NEW/collects/unstable/scribblings/hash.scrbl > @@ -67,57 +67,6 @@ applying @scheme[f] (in tail position) if @scheme[h] has > no entry for > > } > > -...@section{hash Table Accessors} > - > -...@defproc[(hash-equal? [h hash?]) boolean?]{ > - > -Reports whether @scheme[h] maps keys according to @scheme[equal?]. > - > -...@defexamples[ > -#:eval (eval/require 'unstable/hash) > -(hash-equal? #hash()) > -(hash-equal? #hasheq()) > -(hash-equal? #hasheqv()) > -] > - > -} > - > -...@defproc[(hash-has-key? [h hash?] [k any/c]) boolean?]{ > - > -Reports whether @scheme[h] has an entry for @scheme[k]. This function is > -re-exported from @schememodname[scheme/base]. In versions of Racket before > -...@scheme[hash-has-key?] was implemented, this module provides its own > definition. > - > -...@defexamples[ > -#:eval (eval/require 'unstable/hash) > -(hash-has-key? (make-immutable-hash '([1 . one] [2 . two] [3 . three])) 2) > -(hash-has-key? (make-immutable-hash '([1 . one] [2 . two] [3 . three])) 4) > -] > - > -} > - > -...@defproc[(hash-domain [h hash?]) list?]{ > - > -Produces the domain of a hash table as a list of keys. > - > -...@defexamples[ > -#:eval (eval/require 'unstable/hash) > -(hash-domain (make-immutable-hash '([1 . one] [2 . two] [3 . three]))) > -] > - > -} > - > -...@defproc[(hash-range [h hash?]) list?]{ > - > -Produces the range of a hash table as a list of values. > - > -...@defexamples[ > -#:eval (eval/require 'unstable/hash) > -(hash-range (make-immutable-hash '([1 . one] [2 . two] [3 . three]))) > -] > - > -} > - > �...@section{hash Table Combinations} > > �...@defproc[(hash-union [h0 (and/c hash? hash-can-functional-set?)] > -- Jay McCarthy <j...@cs.byu.edu> Assistant Professor / Brigham Young University http://teammccarthy.org/jay "The glory of God is Intelligence" - D&C 93 _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev