diff --git a/collects/racket/private/hash.rkt b/collects/racket/private/hash.rkt index dbaf0ba16c..223ee55e9d 100644 --- a/collects/racket/private/hash.rkt +++ b/collects/racket/private/hash.rkt @@ -8,6 +8,26 @@ (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)) \ No newline at end of file + hash->list + hash-set* + hash-set*!)) \ No newline at end of file diff --git a/collects/scribblings/reference/hashes.scrbl b/collects/scribblings/reference/hashes.scrbl index 21e2518c5e..2be553d5c5 100644 --- a/collects/scribblings/reference/hashes.scrbl +++ b/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?)] @@ -191,6 +203,20 @@ Functionally extends @scheme[hash] by mapping @scheme[key] to @scheme[v], overwriting any existing mapping for @scheme[key], and 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?] diff --git a/collects/tests/racket/basic.rktl b/collects/tests/racket/basic.rktl index 831c0daba6..cf99c666fe 100644 --- a/collects/tests/racket/basic.rktl +++ b/collects/tests/racket/basic.rktl @@ -2363,9 +2363,39 @@ (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))) +(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)