racket/collects/scribblings/guide/hash-tables.scrbl
2008-04-08 21:42:38 +00:00

79 lines
2.4 KiB
Racket

#lang scribble/doc
@(require scribble/manual
scribble/eval
"guide-utils.ss")
@title[#:tag "hash-tables"]{Hash Tables}
A @defterm{hash table} implements a mapping from keys to values, where
both keys and values can be arbitrary Scheme values, and access and
update to the table are normally constant-time operations. Keys are
compared using @scheme[equal?] or @scheme[eq?], depending on whether
the hash table is created with @scheme[make-hash] or
@scheme[make-hasheq].
@examples[
(define ht (make-hash))
(hash-set! ht "apple" '(red round))
(hash-set! ht "banana" '(yellow long))
(hash-ref ht "apple")
(hash-ref ht "coconut")
(hash-ref ht "coconut" "not there")
]
A literal hash table can be written as an expression by using
@litchar{#hash} (for an @scheme[equal?]-based table) or
@litchar{#hasheq} (for an @scheme[eq?]-based table). A parenthesized
sequence must immediately follow @litchar{#hash} or @litchar{#hasheq},
where each element is a sequence is a dotted key--value pair. Literal
hash tables are immutable, but they can be extended functionally
(producing a new hash table without changing the old one) using
@scheme[hash-set].
@examples[
(define ht #hash(("apple" . red)
("banana" . yellow)))
(hash-ref ht "apple")
(define ht2 (hash-set ht "coconut" 'brown))
(hash-ref ht "coconut")
(hash-ref ht2 "coconut")
ht2
]
@refdetails/gory["parse-hashtable"]{the syntax of hash table literals}
A hash table can optionally retain its keys @defterm{weakly}, so each
mapping is retained only so long as the key is retained elsewhere.
@examples[
(define ht (make-weak-hasheq))
(hash-set! ht (gensym) "can you see me?")
(collect-garbage)
(eval:alts (hash-count ht) 0)
]
Beware that even a weak hash table retains its values strongly, as
long as the corresponding key is accessible. This creates a catch-22
dependency when a value refers back to its key, so that the mapping is
retained permanently. To break the cycle, map the key to an
@seclink["ephemerons"]{ephemeron} that pairs the value with its key (in
addition to the implicit pairing of the hash table).
@examples[
(define ht (make-weak-hasheq))
(let ([g (gensym)])
(hash-set! ht g (list g)))
(collect-garbage)
(eval:alts (hash-count ht) 1)
]
@interaction[
(define ht (make-weak-hasheq))
(let ([g (gensym)])
(hash-set! ht g (make-ephemeron g (list g))))
(collect-garbage)
(eval:alts (hash-count ht) 0)
]
@refdetails["hashtables"]{hash tables and hash-table procedures}