concept-hash-tables.tex 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. % -*- Mode: TeX -*-
  2. \beginsubsection{Hash-Table Operations}
  3. \Thenextfigure\ lists some \term{defined names} that are applicable
  4. to \term{hash tables}. The following rules apply to \term{hash tables}.
  5. %% 16.0.0 2
  6. %% 16.0.0 4
  7. \beginlist
  8. \itemitem{--}
  9. A \term{hash table} can only associate one value with a given
  10. key. If an attempt is made to add a second value for a given key,
  11. the second value will replace the first.
  12. Thus, adding a value to a \term{hash table} is a destructive operation;
  13. the \term{hash table} is modified.
  14. %% 16.0.0 5
  15. \itemitem{--}
  16. There are four kinds of \term{hash tables}:
  17. those whose keys are compared with \funref{eq},
  18. those whose keys are compared with \funref{eql},
  19. those whose keys are compared with \funref{equal}, and
  20. \issue{HASH-TABLE-TESTS:ADD-EQUALP}
  21. those whose keys are compared with \funref{equalp}.
  22. \endissue{HASH-TABLE-TESTS:ADD-EQUALP}
  23. %% 16.0.0 6
  24. \itemitem{--}
  25. \term{Hash tables} are created by \funref{make-hash-table}.
  26. \funref{gethash} is used to look up a key and find the associated value.
  27. New entries are added to \term{hash tables} using \macref{setf} with \funref{gethash}.
  28. \funref{remhash} is used to remove an entry.
  29. For example:
  30. \code
  31. (setq a (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32536573>
  32. (setf (gethash 'color a) 'brown) \EV BROWN
  33. (setf (gethash 'name a) 'fred) \EV FRED
  34. (gethash 'color a) \EV BROWN, \term{true}
  35. (gethash 'name a) \EV FRED, \term{true}
  36. (gethash 'pointy a) \EV NIL, \term{false}
  37. \endcode
  38. %% 16.0.0 7
  39. In this example, the symbols \f{color} and \f{name} are being used as
  40. keys, and the symbols \f{brown} and \f{fred} are being used as the
  41. associated values. The \term{hash table}
  42. has two items in it, one of which
  43. associates from \f{color} to \f{brown}, and the other of which
  44. associates from \f{name} to \f{fred}.
  45. %% 16.0.0 8
  46. \itemitem{--}
  47. A key or a value may be any \term{object}.
  48. \issue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
  49. % The following will be deleted.
  50. %
  51. % %% 16.0.0 9
  52. % \itemitem{--}
  53. % A \term{hash table}'s size is the maximum number of entries
  54. % it can hold without collisions. Usually the actual capacity of
  55. % the table is somewhat less, since the hashing is not perfectly
  56. % collision-free. If so many entries are
  57. % added that the capacity is exceeded, the \term{hash table}
  58. % will automatically
  59. % grow, and the entries will be rehashed (new hash values will be
  60. % recomputed, and everything will be rearranged so that the fast hash
  61. % lookup still works). This is transparent to the caller; it all happens
  62. % automatically.
  63. \endissue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
  64. %% 16.0.0 10
  65. \itemitem{--}
  66. % The cases of \f{nil} as a value and no entry in the \term{hash table}
  67. % can be distinguished by the second value returned by \funref{gethash}.
  68. %% Reworded per Barmar:
  69. The existence of an entry in the \term{hash table} can be determined
  70. from the \term{secondary value} returned by \funref{gethash}.
  71. \endlist
  72. \displaythree{Hash-table defined names}{
  73. clrhash&hash-table-p&remhash\cr
  74. gethash&make-hash-table&sxhash\cr
  75. hash-table-count&maphash&\cr
  76. }
  77. \endsubsection%{Hash-Table Operations}
  78. \beginsubsection{Modifying Hash Table Keys}
  79. \DefineSection{ModifyingHashKeys}
  80. \issue{HASH-TABLE-KEY-MODIFICATION:SPECIFY}
  81. The function supplied as the \kwd{test} argument to \funref{make-hash-table}
  82. specifies the `equivalence test' for the \term{hash table} it creates.
  83. An \term{object} is `visibly modified' with regard to an equivalence test
  84. if there exists some set of \term{objects} (or potential \term{objects})
  85. which are equivalent to the \term{object} before the modification but are
  86. no longer equivalent afterwards.
  87. % If an \term{object} is used as a key in a \term{hash table} and is then visibly
  88. % modified with regard to the equivalence test of the \term{hash table}, then
  89. % using the \term{object} as a key in further operations on the \term{hash table}
  90. % has unspecified consequences. Moreover, this applies for other \term{objects}
  91. % which either are or were equivalent to the key object. Further, undoing the
  92. % modification does not remove this effect.
  93. If an \term{object} $O\sub 1$ is used as a key in a \term{hash table} $H$
  94. and is then visibly modified with regard to the equivalence test of $H$,
  95. then the consequences are unspecified if $O\sub 1$, or any \term{object}
  96. $O\sub 2$ equivalent to $O\sub 1$ under the equivalence test (either before
  97. or after the modification), is used as a key in further operations on $H$.
  98. The consequences of using $O\sub 1$ as a key are unspecified
  99. even if $O\sub 1$ is visibly modified
  100. and then later modified again in such a way as
  101. to undo the visible modification.
  102. Following are specifications of the modifications which are visible to the
  103. equivalence tests which must be supported by \term{hash tables}. The modifications
  104. are described in terms of modification of components, and are defined
  105. recursively. Visible modifications of components of the \term{object} are
  106. visible modifications of the \term{object}.
  107. \beginsubsubsection{Visible Modification of Objects with respect to EQ and EQL}
  108. \DefineSection{VisModEQ}
  109. \DefineSection{VisModEQL}
  110. No \term{standardized} \term{function} is provided that is capable of visibly
  111. modifying an \term{object} with regard to \funref{eq} or \funref{eql}.
  112. \endsubsubsection%{Visible Modification of Objects with respect to EQ and EQL}
  113. \beginsubsubsection{Visible Modification of Objects with respect to EQUAL}
  114. \DefineSection{VisModEQUAL}
  115. As a consequence of the behavior for \funref{equal},
  116. the rules for visible modification of \term{objects} not explicitly mentioned in this
  117. section are inherited from those in \secref\VisModEQL.
  118. \beginsubsubsubsection{Visible Modification of Conses with respect to EQUAL}
  119. Any visible change to the \term{car} or the \term{cdr} of a \term{cons}
  120. is considered a visible modification with regard to \funref{equal}.
  121. \endsubsubsubsection%{Visible Modification of Conses with respect to EQUAL}
  122. \beginsubsubsubsection{Visible Modification of Bit Vectors and Strings with respect to EQUAL}
  123. For a \term{vector} \oftype{bit-vector} or \oftype{string}, any visible change
  124. to an \term{active} \term{element} of the \term{vector},
  125. or to the \term{length} of the \term{vector} (if it is \term{actually adjustable}
  126. or has a \term{fill pointer})
  127. is considered a visible modification with regard to \funref{equal}.
  128. \endsubsubsubsection%{Visible Modification of Bit Vectors and Strings with respect to EQUAL}
  129. \endsubsubsection%{Visible Modification of Objects with respect to EQUAL}
  130. \beginsubsubsection{Visible Modification of Objects with respect to EQUALP}
  131. As a consequence of the behavior for \funref{equalp},
  132. the rules for visible modification of \term{objects} not explicitly mentioned in this
  133. section are inherited from those in \secref\VisModEQUAL.
  134. \beginsubsubsubsection{Visible Modification of Structures with respect to EQUALP}
  135. Any visible change to a \term{slot} of a \term{structure}
  136. is considered a visible modification with regard to \funref{equalp}.
  137. \endsubsubsubsection%{Visible Modification of Structures with respect to EQUALP}
  138. \beginsubsubsubsection{Visible Modification of Arrays with respect to EQUALP}
  139. In an \term{array}, any visible change
  140. to an \term{active} \term{element},
  141. to the \term{fill pointer} (if the \term{array} can and does have one),
  142. or to the \term{dimensions} (if the \term{array} is \term{actually adjustable})
  143. is considered a visible modification with regard to \funref{equalp}.
  144. \endsubsubsubsection%{Visible Modification of Arrays with respect to EQUALP}
  145. \beginsubsubsubsection{Visible Modification of Hash Tables with respect to EQUALP}
  146. In a \term{hash table}, any visible change
  147. to the count of entries in the \term{hash table},
  148. to the keys,
  149. or to the values associated with the keys
  150. is considered a visible modification with regard to \funref{equalp}.
  151. Note that the visibility of modifications to the keys depends on the equivalence test
  152. of the \term{hash table}, not on the specification of \funref{equalp}.
  153. \endsubsubsubsection%{Visible Modification of Hash Tables with respect to EQUALP}
  154. \endsubsubsection%{Visible Modification of Objects with respect to EQUALP}
  155. \beginsubsubsection{Visible Modifications by Language Extensions}
  156. \term{Implementations} that extend the language by providing additional mutator
  157. functions (or additional behavior for existing mutator functions) must
  158. document how the use of these extensions interacts with equivalence tests and
  159. \term{hash table} searches.
  160. \term{Implementations} that extend the language by defining additional acceptable
  161. equivalence tests for \term{hash tables} (allowing additional values for the \kwd{test}
  162. argument to \funref{make-hash-table}) must document the visible components of these
  163. tests.
  164. \endsubsubsection%{Visible Modifications by Language Extensions}
  165. % !!! Maybe consider making these things visible...
  166. %
  167. % Test Cases/Examples:
  168. %
  169. % (setf ht (make-hash-table :test #'eq))
  170. % (setf a (cons 1 2))
  171. % (setf (gethash a ht) 'win)
  172. % (setf (cdr a) 3)
  173. % (gethash a ht 'lose) => win t
  174. %
  175. % The same example with :test #'equal in the first line would be an error.
  176. %
  177. % The following example is not an error, because EQUAL does not examine the
  178. % components of general vectors:
  179. %
  180. % (setf ht (make-hash-table :test #'equal))
  181. % (setf a (vector 1 2))
  182. % (setf (gethash a ht) 'win)
  183. % (setf (aref a 1) 3)
  184. % (gethash a ht 'lose) => win t
  185. %
  186. % The following example is not an error, because EQUALP is limited by the
  187. % fill-pointer when examining the elements of a vector:
  188. %
  189. % (setf ht (make-hash-table :test #'equalp))
  190. % (setf a (make-array 3 :fill-pointer 2 :initial-contents '(1 2 3)))
  191. % (setf (gethash a ht) 'win)
  192. % (setf (aref a 2) 4)
  193. % (gethash a ht 'lose) => win t
  194. %
  195. % The following example is an error, because EQUALP may examine the dimensions
  196. % of arrays:
  197. %
  198. % (setf ht (make-hash-table :test #'equalp))
  199. % (setf a (make-array '(2 3) :adjustable t))
  200. % (setf (gethash a ht) 'win)
  201. % (setf a (adjust-array a '(3 2)))
  202. % (gethash a ht 'lose) => `unspecified'
  203. %
  204. % The following example is not an error, because EQUALP is case insensitive:
  205. %
  206. % (setf ht (make-hash-table :test #'equalp))
  207. % (setf a "ABC")
  208. % (setf (gethash a ht) 'win)
  209. % (setf (char a 0) #\a)
  210. % (gethash a ht 'lose) => win t
  211. %
  212. % The same example with :test #'equal in the first line would be an error.
  213. %
  214. \endissue{HASH-TABLE-KEY-MODIFICATION:SPECIFY}
  215. \endsubsection%{Modifying Hash Table Keys}