72 lines
2.3 KiB
Racket
72 lines
2.3 KiB
Racket
#lang scribble/doc
|
|
@require[scribble/manual]
|
|
@require[scribble/eval]
|
|
@require["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 the @scheme['equal] flag.
|
|
|
|
@examples[
|
|
(define ht (make-hash-table 'equal))
|
|
(hash-table-put! ht "apple" '(red round))
|
|
(hash-table-put! ht "banana" '(yellow long))
|
|
(hash-table-get ht "apple")
|
|
(hash-table-get ht "coconut")
|
|
(hash-table-get 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.
|
|
|
|
@examples[
|
|
(define ht #hash(("apple" . (red round))
|
|
("banana" . (yellow long))))
|
|
(hash-table-get ht "apple")
|
|
]
|
|
|
|
@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-hash-table 'weak))
|
|
(hash-table-put! ht (gensym) "can you see me?")
|
|
(collect-garbage)
|
|
(eval:alts (hash-table-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-hash-table 'weak))
|
|
(let ([g (gensym)])
|
|
(hash-table-put! ht g (list g)))
|
|
(collect-garbage)
|
|
(eval:alts (hash-table-count ht) 1)
|
|
]
|
|
|
|
@interaction[
|
|
(define ht (make-hash-table 'weak))
|
|
(let ([g (gensym)])
|
|
(hash-table-put! ht g (make-ephemeron g (list g))))
|
|
(collect-garbage)
|
|
(eval:alts (hash-table-count ht) 0)
|
|
]
|
|
|
|
@refdetails["hashtables"]{hash tables and hash-table procedures}
|