123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985 |
- % -*- Mode: TeX -*-
- %
- % !!!
- % Barrett:
- % What about errors for these?
- %
- % !!!
- % JonL:
- % I'll bet we don't define "grow" (as a verb -- trivial point would be to
- % put this in passive voice rather than active; better, simply say "before
- % the table size has to be enlarged.")
- % Given that fuzziness (about "grow") it is still unclear what the interaction
- % between SIZE and THRESHOLD is. Since THRESHOLD later is described as being
- % merely a "hint", then maybe all one needs to say is that the the programmer
- % is permitted to express his intent that no enlargements will be forced until
- % after about SIZE different entries have been made, and at that the time of
- % enlargement, the actual storage size of the table may be larger than SIZE by
- % an amount indicated by the THRESHOLD parameter -- that is the SIZE parameter
- % will be at the "threshold" value rather than the "actual size" value.
- %-------------------- Hash-Table Type --------------------
- \begincom{hash-table}\ftype{System Class}
- \label Class Precedence List::
- \typeref{hash-table},
- \typeref{t}
- \label Description::
- %% 16.0.0 3 (has been mostly gutted)
- \term{Hash tables} provide a way of mapping any \term{object} (a \term{key})
- to an associated \term{object} (a \term{value}).
- \label See Also::
- {\secref\HashTableConcepts},
- {\secref\PrintingOtherObjects}
- \label Notes::
- % This is to satisfy JonL.
- The intent is that this mapping be implemented by a hashing mechanism,
- such as that described in Section 6.4 ``Hashing'' of {\KnuthVolThree}
- (pp506-549). In spite of this intent, no \term{conforming implementation}
- is required to use any particular technique to implement the mapping.
- \endcom%{hash-table}\ftype{System Class}
- %%% ========== MAKE-HASH-TABLE
- \begincom{make-hash-table}\ftype{Function}
- \label Syntax::
- \DefunWithValues make-hash-table {{\key} test size rehash-size rehash-threshold}
- {hash-table}
- \label Arguments and Values::
- \param{test}---a \term{designator} for one of the \term{functions}
- \funref{eq},
- \funref{eql},
- \funref{equal}, or
- \issue{HASH-TABLE-TESTS:ADD-EQUALP}
- \funref{equalp}.
- \endissue{HASH-TABLE-TESTS:ADD-EQUALP}
- \Default{\funref{eql}}
- %% 16.0.0 13
- \issue{ARGUMENTS-UNDERSPECIFIED:SPECIFY}
- \param{size}---a non-negative \term{integer}.
- \endissue{ARGUMENTS-UNDERSPECIFIED:SPECIFY}
- \Default{\term{implementation-dependent}}
- %% 16.0.0 14
- \param{rehash-size}---a \term{real} of \term{type} \f{(or (integer 1 *) (float (1.0) *))}.
- \Default{\term{implementation-dependent}}
- %% 16.0.0 15
- \issue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- \param{rehash-threshold}---a \term{real} of \term{type} \f{(real 0 1)}.
- \Default{\term{implementation-dependent}}
- % KMP thinks HASH-TABLE-SIZE:INTENDED-ENTRIES implies this can no longer be an integer.
- % Moon concurs.
- \endissue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- \param{hash-table}---a \term{hash table}.
- \label Description::
- %% 16.0.0 12
- Creates and returns a new \term{hash table}.
- \param{test} determines how \term{keys} are compared.
- %This seemed to need elaboration, so I added the rest of this paragraph. -kmp 27-Feb-91
- An \term{object} is said to be present in the \param{hash-table}
- if that \term{object} is the \term{same} under the \term{test}
- as the \term{key} for some entry in the \param{hash-table}.
- \param{size} is a hint to the \term{implementation} about how much initial space
- to allocate in the \param{hash-table}.
- \issue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- %It specifies
- %% For JonL, I substituted the next line:
- This information, taken together with the \param{rehash-threshold}, controls
- the approximate number of entries which it should be possible
- to insert before the table has to grow.
- \endissue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- The actual size might be rounded up from \param{size} to the next `good' size;
- for example, some \term{implementations} might round to the next prime number.
- \param{rehash-size} specifies a minimum amount to increase the size of the
- \param{hash-table} when it becomes full
- enough to require rehashing;
- see \param{rehash-theshold} below.
- \issue{HASH-TABLE-REHASH-SIZE-INTEGER}
- If \param{rehash-size} is an \term{integer},
- the expected growth rate for the table is additive and
- the \term{integer} is the number of entries to add;
- if it is a \term{float},
- the expected growth rate for the table is multiplicative and
- the \term{float} is the ratio of the new size to the old size.
- \endissue{HASH-TABLE-REHASH-SIZE-INTEGER}
- As with \param{size}, the actual size of the increase might be rounded up.
- \param{rehash-threshold} specifies how full the \param{hash-table} can get
- before it must grow.
- \issue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- It specifies the maximum desired hash-table occupancy level.
- %If \param{rehash-threshold} is an \term{integer}
- %it will be scaled whenever the table is grown.
- \issue{HASH-TABLE-REHASH-SIZE-INTEGER}
- The \term{values} of \param{rehash-size} and \param{rehash-threshold} do not constrain the
- \term{implementation} to use any particular method for computing when and by how much
- the size of \param{hash-table} should be enlarged. Such decisions are
- \term{implementation-dependent}, and these \term{values} only hints
- from the \term{programmer} to the \term{implementation}, and the \term{implementation}
- is permitted to ignore them.
- \endissue{HASH-TABLE-REHASH-SIZE-INTEGER}
- \endissue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- \label Examples::
- %% 16.0.0 16
- \code
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 46142754>
- (setf (gethash "one" table) 1) \EV 1
- (gethash "one" table) \EV NIL, \term{false}
- (setq table (make-hash-table :test 'equal)) \EV #<HASH-TABLE EQUAL 0/139 46145547>
- (setf (gethash "one" table) 1) \EV 1
- (gethash "one" table) \EV 1, T
- (make-hash-table :rehash-size 1.5 :rehash-threshold 0.7)
- \EV #<HASH-TABLE EQL 0/120 46156620>
- \endcode
- \issue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- % I removed this example because it uses an integer :rehash-threshold. -kmp 21-May-91
- % (make-hash-table :size 100 :rehash-size 50 :rehash-threshold 75)
- % \EV #<HASH-TABLE EQL 0/100 46152651>
- \endissue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \funref{gethash},
- \typeref{hash-table}
- \label Notes:\None.
- %% JonL says this is "redundant, and perhaps confusing". -kmp 3-Feb-92
- % There are \term{hash tables} that hash on \term{object} identity
- % (using \funref{eq} or \funref{eql})
- % and there are \term{hash tables} that hash on \term{object} structure
- % (using \funref{equal} and \funref{equalp}).
- \endcom
- %%% ========== HASH-TABLE-P
- \begincom{hash-table-p}\ftype{Function}
- \label Syntax::
- \DefunWithValues hash-table-p {object} {generalized-boolean}
- \label Arguments and Values::
- \param{object}---an \term{object}.
- \param{generalized-boolean}---a \term{generalized boolean}.
- \label Description::
- %% 16.0.0 17
- \TypePredicate{object}{hash-table}
- \label Examples::
- \code
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32511220>
- (hash-table-p table) \EV \term{true}
- (hash-table-p 37) \EV \term{false}
- (hash-table-p '((a . 1) (b . 2))) \EV \term{false}
- \endcode
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations:\None!
- \label See Also:\None.
- \label Notes::
- \code
- (hash-table-p \param{object}) \EQ (typep \param{object} 'hash-table)
- \endcode
- \endcom
- %%% ========== HASH-TABLE-COUNT
- \begincom{hash-table-count}\ftype{Function}
- \label Syntax::
- \DefunWithValues hash-table-count {hash-table} {count}
- \label Arguments and Values::
- \param{hash-table}---a \term{hash table}.
- \param{count}---a non-negative \term{integer}.
- \label Description::
- %% 16.0.0 25
- Returns the number of entries in the \param{hash-table}.
- If \param{hash-table} has just been created
- or newly cleared (see \funref{clrhash})
- the entry count is \f{0}.
- \label Examples::
- \code
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32115135>
- (hash-table-count table) \EV 0
- (setf (gethash 57 table) "fifty-seven") \EV "fifty-seven"
- (hash-table-count table) \EV 1
- (dotimes (i 100) (setf (gethash i table) i)) \EV NIL
- (hash-table-count table) \EV 100
- \endcode
- \label Side Effects:\None.
- \label Affected By::
- \funref{clrhash},
- \funref{remhash},
- \SETFof{gethash}
- \label Exceptional Situations:\None.
- \label See Also::
- \funref{hash-table-size}
- \label Notes::
- The following relationships are functionally correct, although in practice
- using \funref{hash-table-count} is probably much faster:
- \code
- (hash-table-count \param{table}) \EQ
- (loop for value being the hash-values of \param{table} count t) \EQ
- (let ((total 0))
- (maphash #'(lambda (key value)
- (declare (ignore key value))
- (incf total))
- \param{table})
- total)
- \endcode
- \endcom
- %%% ========== HASH-TABLE-REHASH-SIZE
- \begincom{hash-table-rehash-size}\ftype{Function}
- \issue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \label Syntax::
- \DefunWithValues hash-table-rehash-size {hash-table} {rehash-size}
- \label Arguments and Values::
- \param{hash-table}---a \term{hash table}.
- \param{rehash-size}---a \term{real} of \term{type} \f{(or (integer 1 *) (float (1.0) *))}.
- \label Description::
- Returns the current rehash size of \param{hash-table},
- suitable for use in a call to \funref{make-hash-table}
- in order to produce a \term{hash table}
- with state corresponding to the current state of the \param{hash-table}.
- \label Examples::
- \code
- (setq table (make-hash-table :size 100 :rehash-size 1.4))
- \EV #<HASH-TABLE EQL 0/100 2556371>
- (hash-table-rehash-size table) \EV 1.4
- \endcode
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- \Shouldchecktype{hash-table}{a \term{hash table}}
- \label See Also::
- \funref{make-hash-table},
- \funref{hash-table-rehash-threshold}
- \label Notes::
- \issue{HASH-TABLE-REHASH-SIZE-INTEGER}
- If the hash table was created with an \term{integer} rehash size,
- the result is an \term{integer},
- indicating that the rate of growth of the \param{hash-table} when rehashed
- is intended to be additive;
- otherwise,
- the result is a \term{float},
- indicating that the rate of growth of the \param{hash-table} when rehashed
- is intended to be multiplicative.
- However, this value is only advice to the \term{implementation};
- the actual amount by which the \param{hash-table} will grow upon rehash is
- \term{implementation-dependent}.
- \endissue{HASH-TABLE-REHASH-SIZE-INTEGER}
- \endissue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \endcom
- %%% ========== HASH-TABLE-REHASH-THRESHOLD
- \begincom{hash-table-rehash-threshold}\ftype{Function}
- \issue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \label Syntax::
- \DefunWithValues hash-table-rehash-threshold {hash-table} {rehash-threshold}
- \label Arguments and Values::
- \param{hash-table}---a \term{hash table}.
- \issue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- \param{rehash-threshold}---a \term{real} of \term{type} \f{(real 0 1)}.
- % KMP thinks HASH-TABLE-SIZE:INTENDED-ENTRIES implies this can no longer be an integer.
- % Moon concurs.
- \endissue{HASH-TABLE-SIZE:INTENDED-ENTRIES}
- \label Description::
- Returns the current rehash threshold of \param{hash-table}, which is
- suitable for use in a call to \funref{make-hash-table} in order to
- produce a \term{hash table} with state corresponding to the current
- state of the \param{hash-table}.
- \label Examples::
- \code
- (setq table (make-hash-table :size 100 :rehash-threshold 0.5))
- \EV #<HASH-TABLE EQL 0/100 2562446>
- (hash-table-rehash-threshold table) \EV 0.5
- \endcode
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- \Shouldchecktype{hash-table}{a \term{hash table}}
- \label See Also::
- \funref{make-hash-table},
- \funref{hash-table-rehash-size}
- %% Per X3J13. -kmp 05-Oct-93
- \label Notes:\None.
- \endissue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \endcom
- %%% ========== HASH-TABLE-SIZE
- \begincom{hash-table-size}\ftype{Function}
- \issue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \label Syntax::
- \DefunWithValues hash-table-size {hash-table} {size}
- \label Arguments and Values::
- \param{hash-table}---a \term{hash table}.
- \param{size}---a non-negative \term{integer}.
- \label Description::
- Returns the current size of \param{hash-table}, which is suitable for use in
- a call to \funref{make-hash-table} in order to produce a \term{hash table}
- with state corresponding to the current state of the \param{hash-table}.
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- \Shouldchecktype{hash-table}{a \term{hash table}}
- \label See Also::
- \funref{hash-table-count},
- \funref{make-hash-table}
- %% Per X3J13. -kmp 05-Oct-93
- \label Notes:\None.
- \endissue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \endcom
- %%% ========== HASH-TABLE-TEST
- \begincom{hash-table-test}\ftype{Function}
- \issue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \label Syntax::
- \DefunWithValues hash-table-test {hash-table} {test}
- \label Arguments and Values::
- \param{hash-table}---a \term{hash table}.
- \param{test}---a \term{function designator}.
- For the four \term{standardized} \term{hash table} test \term{functions}
- (see \funref{make-hash-table}), the \param{test} value returned
- is always a \term{symbol}. If an \term{implementation} permits additional
- tests, it is \term{implementation-dependent} whether such tests are
- returned as \term{function} \term{objects} or \term{function names}.
- \label Description::
- Returns the test used for comparing \term{keys} in \param{hash-table}.
- \label Examples:\None.
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- \Shouldchecktype{hash-table}{a \term{hash table}}
- \label See Also::
- \funref{make-hash-table}
- %% Per X3J13. -kmp 05-Oct-93
- \label Notes:\None.
- \endissue{HASH-TABLE-ACCESS:X3J13-MAR-89}
- \endcom
- %%% ========== GETHASH
- \begincom{gethash}\ftype{Accessor}
- \label Syntax::
- \DefunWithValues gethash {key hash-table {\opt} default} {value, present-p}
- \Defsetf gethash {key hash-table {\opt} default} {new-value}
- \label Arguments and Values::
- \param{key}---an \term{object}.
- \param{hash-table}---a \term{hash table}.
- \param{default}---an \term{object}.
- \Default{\nil}
- \param{value}---an \term{object}.
- \param{present-p}---a \term{generalized boolean}.
- \label Description::
- %% 16.0.0 18
- \param{Value} is the \term{object} in \param{hash-table} whose \term{key}
- is the \term{same} as \param{key} under the \param{hash-table}'s equivalence test.
- If there is no such entry, \param{value} is the \param{default}.
- %% 16.0.0 19
- \param{Present-p} is \term{true} if an entry is found; otherwise, it is \term{false}.
- %% 16.0.0 20
- \macref{setf} may be used with \funref{gethash} to modify the \term{value}
- associated with a given \term{key}, or to add a new entry.
- \issue{SETF-GET-DEFAULT:EVALUATED-BUT-IGNORED}
- When a \funref{gethash} \term{form} is used as a \macref{setf} \param{place},
- any \param{default} which is supplied is evaluated according to normal
- left-to-right evaluation rules, but its \term{value} is ignored.
- % \param{Default} may be supplied to \funref{gethash}
- % in this context; it is ignored by the
- % \macref{setf} expander function for \funref{gethash}, but
- % may be useful in such macros
- % as \macref{incf} that are related to \macref{setf}:
- \endissue{SETF-GET-DEFAULT:EVALUATED-BUT-IGNORED}
- \label Examples::
- \code
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32206334>
- (gethash 1 table) \EV NIL, \term{false}
- (gethash 1 table 2) \EV 2, \term{false}
- (setf (gethash 1 table) "one") \EV "one"
- (setf (gethash 2 table "two") "two") \EV "two"
- (gethash 1 table) \EV "one", \term{true}
- (gethash 2 table) \EV "two", \term{true}
- (gethash nil table) \EV NIL, \term{false}
- (setf (gethash nil table) nil) \EV NIL
- (gethash nil table) \EV NIL, \term{true}
- (defvar *counters* (make-hash-table)) \EV *COUNTERS*
- (gethash 'foo *counters*) \EV NIL, \term{false}
- (gethash 'foo *counters* 0) \EV 0, \term{false}
- (defmacro how-many (obj) `(values (gethash ,obj *counters* 0))) \EV HOW-MANY
- (defun count-it (obj) (incf (how-many obj))) \EV COUNT-IT
- (dolist (x '(bar foo foo bar bar baz)) (count-it x))
- (how-many 'foo) \EV 2
- (how-many 'bar) \EV 3
- (how-many 'quux) \EV 0
- \endcode
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \funref{remhash}
- \label Notes::
- The \term{secondary value}, \param{present-p},
- can be used to distinguish the absence of an entry
- from the presence of an entry that has a value of \param{default}.
- \endcom
- %%% ========== REMHASH
- \begincom{remhash}\ftype{Function}
- \label Syntax::
- \DefunWithValues remhash {key hash-table} {generalized-boolean}
- \label Arguments and Values::
- \param{key}---an \term{object}.
- \param{hash-table}---a \term{hash table}.
- \param{generalized-boolean}---a \term{generalized boolean}.
- \label Description::
- %% 16.0.0 21
- Removes the entry for \param{key} in \param{hash-table}, if any.
- Returns \term{true} if there was such an entry, or \term{false} otherwise.
- \label Examples::
- \code
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32115666>
- (setf (gethash 100 table) "C") \EV "C"
- (gethash 100 table) \EV "C", \term{true}
- (remhash 100 table) \EV \term{true}
- (gethash 100 table) \EV NIL, \term{false}
- (remhash 100 table) \EV \term{false}
- \endcode
- \label Side Effects::
- The \param{hash-table} is modified.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also:\None.
- \label Notes:\None.
- \endcom
- %%% ========== MAPHASH
- \begincom{maphash}\ftype{Function}
- \label Syntax::
- %% 16.0.0 23
- \DefunWithValues maphash {function hash-table} {\nil}
- \label Arguments and Values::
- \param{function}---a \term{designator} for a \term{function} of two \term{arguments},
- the \term{key} and the \term{value}.
- \param{hash-table}---a \term{hash table}.
- \label Description::
- %% 16.0.0 22
- Iterates over all entries in the \param{hash-table}. For each entry,
- the \param{function} is called with two \term{arguments}--the \term{key}
- and the \term{value} of that entry.
- The consequences are unspecified if any attempt is made to add or remove
- an entry from the \param{hash-table} while a \funref{maphash} is in progress,
- with two exceptions:
- the \param{function} can use can use \macref{setf} of \funref{gethash}
- to change the \term{value} part of the entry currently being processed,
- or it can use \funref{remhash} to remove that entry.
- \label Examples::
- \code
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32304110>
- (dotimes (i 10) (setf (gethash i table) i)) \EV NIL
- (let ((sum-of-squares 0))
- (maphash #'(lambda (key val)
- (let ((square (* val val)))
- (incf sum-of-squares square)
- (setf (gethash key table) square)))
- table)
- sum-of-squares) \EV 285
- (hash-table-count table) \EV 10
- (maphash #'(lambda (key val)
- (when (oddp val) (remhash key table)))
- table) \EV NIL
- (hash-table-count table) \EV 5
- (maphash #'(lambda (k v) (print (list k v))) table)
- (0 0)
- (8 64)
- (2 4)
- (6 36)
- (4 16)
- \EV NIL
- \endcode
- \label Side Effects::
- None, other than any which might be done by the \param{function}.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \macref{loop},
- \macref{with-hash-table-iterator},
- \issue{MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE}
- {\secref\TraversalRules}
- \endissue{MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE}
- \label Notes:\None.
- \endcom
- %%% ========== WITH-HASH-TABLE-ITERATOR
- \begincom{with-hash-table-iterator}\ftype{Macro}
- \issue{DECLS-AND-DOC}
- \issue{HASH-TABLE-PACKAGE-GENERATORS:ADD-WITH-WRAPPER}
- \label Syntax::
- \DefmacWithValues with-hash-table-iterator
- {\paren{name hash-table}
- \starparam{declaration} \starparam{form}}
- {\starparam{result}}
- \label Arguments and Values::
- \param{name}---a name suitable for the first argument to \specref{macrolet}.
- \param{hash-table}---a \term{form}, evaluated once, that should produce a \term{hash table}.
- \param{declaration}---a \misc{declare} \term{expression}; \noeval.
- \param{forms}---an \term{implicit progn}.
-
- \param{results}---the \term{values} returned by \param{forms}.
- \label Description::
- %!!! KMP: Are declarations permitted?
- % JonL: Let's say No because this provides no name bindings, except for the MACROLET.
- % Can always use LOCALLY anyway.
- % KMP&Barrett: We added them anyway.
- Within the lexical scope of the body, \param{name} is defined via \specref{macrolet}
- such that successive invocations of \f{(\param{name})} return the items,
- one by one, from the \term{hash table} that is obtained by evaluating
- \param{hash-table} only once.
-
- An invocation \f{(\param{name})} returns three values as follows:
- \beginlist
- %\itemitem{1.} A flag indicating whether an entry is returned
- % (true means an entry is returned).
- \itemitem{1.} A \term{generalized boolean} that is \term{true} if an entry is returned.
- \itemitem{2.} The key from the \param{hash-table} entry.
- \itemitem{3.} The value from the \param{hash-table} entry.
- \endlist
- After all entries have been returned by successive invocations of
- \f{(\param{name})}, then only one value is returned, namely \nil.
-
- %!!! Barrett: Doesn't this just mean the macro has dynamic extent?
- It is unspecified what happens if any of the implicit interior state
- of an iteration is returned outside the dynamic extent of the
- \macref{with-hash-table-iterator} \term{form}
- such as by returning some \term{closure} over the invocation \term{form}.
-
- Any number of invocations of \macref{with-hash-table-iterator}
- can be nested, and the body of the innermost one can invoke all of the
- locally \term{established} \term{macros}, provided all of those \term{macros}
- have \term{distinct} names.
- \label Examples::
-
- The following function should return \t\ on any
- \term{hash table}, and signal
- an error if the usage of \macref{with-hash-table-iterator} does not agree
- with the corresponding usage of \funref{maphash}.
-
- \code
- (defun test-hash-table-iterator (hash-table)
- (let ((all-entries '())
- (generated-entries '())
- (unique (list nil)))
- (maphash #'(lambda (key value) (push (list key value) all-entries))
- hash-table)
- (with-hash-table-iterator (generator-fn hash-table)
- (loop
- (multiple-value-bind (more? key value) (generator-fn)
- (unless more? (return))
- (unless (eql value (gethash key hash-table unique))
- (error "Key ~S not found for value ~S" key value))
- (push (list key value) generated-entries))))
- (unless (= (length all-entries)
- (length generated-entries)
- (length (union all-entries generated-entries
- :key #'car :test (hash-table-test hash-table))))
- (error "Generated entries and Maphash entries don't correspond"))
- t))
- \endcode
- % "#'equal" => "(hash-table-test hash-table)" in the above per JonL.
- % There are maybe other problems as well. Mail sent to Quinquevirate.
- % -kmp 2-Feb-92
- The following could be an acceptable definition of
- \funref{maphash}, implemented by \macref{with-hash-table-iterator}.
-
- \code
- (defun maphash (function hash-table)
- (with-hash-table-iterator (next-entry hash-table)
- (loop (multiple-value-bind (more key value) (next-entry)
- (unless more (return nil))
- (funcall function key value)))))
- \endcode
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- The consequences are undefined if the local function named \param{name}
- \term{established} by \macref{with-hash-table-iterator} is called after it has
- returned \term{false} as its \term{primary value}.
- \label See Also::
- \issue{MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE}
- {\secref\TraversalRules}
- \endissue{MAPPING-DESTRUCTIVE-INTERACTION:EXPLICITLY-VAGUE}
- \label Notes:\None.
- \endissue{HASH-TABLE-PACKAGE-GENERATORS:ADD-WITH-WRAPPER}
- \endissue{DECLS-AND-DOC}
- \endcom
- %%% ========== CLRHASH
- \begincom{clrhash}\ftype{Function}
- \label Syntax::
- \DefunWithValues clrhash {hash-table} {hash-table}
- \label Arguments and Values::
- \param{hash-table}---a \term{hash table}.
- \label Description::
- %% 16.0.0 24
- Removes all entries from \param{hash-table},
- and then returns that empty \term{hash table}.
- \label Examples::
- \code
- (setq table (make-hash-table)) \EV #<HASH-TABLE EQL 0/120 32004073>
- (dotimes (i 100) (setf (gethash i table) (format nil "~R" i))) \EV NIL
- (hash-table-count table) \EV 100
- (gethash 57 table) \EV "fifty-seven", \term{true}
- (clrhash table) \EV #<HASH-TABLE EQL 0/120 32004073>
- (hash-table-count table) \EV 0
- (gethash 57 table) \EV NIL, \term{false}
- \endcode
- \label Side Effects::
- The \param{hash-table} is modified.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also:\None.
- \label Notes:\None.
- \endcom
- %%% ========== SXHASH
- \begincom{sxhash}\ftype{Function}
- \issue{SXHASH-DEFINITION:SIMILAR-FOR-SXHASH}
- \label Syntax::
- \DefunWithValues sxhash {object} {hash-code}
- \label Arguments and Values::
- \param{object}---an \term{object}.
- \param{hash-code}---a non-negative \term{fixnum}.
- \label Description::
- %% 16.0.0 27
- \funref{sxhash} returns a hash code for \param{object}.
- The manner in which the hash code is computed is \term{implementation-dependent},
- but subject to certain constraints:
- \beginlist
- \itemitem{1.}
- \f{(equal \param{x} \param{y})} implies \f{(= (sxhash \param{x}) (sxhash \param{y}))}.
- \itemitem{2.}
- For any two \term{objects}, \param{x} and \param{y},
- both of which are
- \term{bit vectors},
- \term{characters},
- \term{conses},
- \term{numbers},
- \term{pathnames},
- \term{strings},
- or \term{symbols},
- and which are \term{similar},
- \f{(sxhash \param{x})} and \f{(sxhash \param{y})}
- \term{yield} the same mathematical value
- even if \param{x} and \param{y} exist in different \term{Lisp images} of
- the same \term{implementation}.
- \Seesection\LiteralsInCompiledFiles.
- \itemitem{3.}
- The \param{hash-code} for an \term{object} is always the \term{same}
- within a single \term{session} provided that the \term{object} is not
- visibly modified with regard to the equivalence test \funref{equal}.
- \Seesection\ModifyingHashKeys.
- \itemitem{4.}
- The \param{hash-code} is intended for hashing. This places no verifiable
- constraint on a \term{conforming implementation}, but the intent is that
- an \term{implementation} should make a good-faith effort to produce
- \param{hash-codes} that are well distributed within the range of
- non-negative \term{fixnums}.
- \itemitem{5.}
- Computation of the \param{hash-code} must terminate,
- even if the \param{object} contains circularities.
- \endlist
- \label Examples::
- \code
- (= (sxhash (list 'list "ab")) (sxhash (list 'list "ab"))) \EV \term{true}
- (= (sxhash "a") (sxhash (make-string 1 :initial-element #\\a))) \EV \term{true}
- (let ((r (make-random-state)))
- (= (sxhash r) (sxhash (make-random-state r))))
- \EV \term{implementation-dependent}
- \endcode
- \label Side Effects:\None.
- \label Affected By::
- The \term{implementation}.
- \label Exceptional Situations:\None!
- \label See Also:\None.
- \label Notes::
- Many common hashing needs are satisfied by \funref{make-hash-table} and the
- related functions on \term{hash tables}. \funref{sxhash} is intended for use
- where the pre-defined abstractions are insufficient. Its main intent is to
- allow the user a convenient means of implementing more complicated hashing
- paradigms than are provided through \term{hash tables}.
- The hash codes returned by \funref{sxhash} are not necessarily related to
- any hashing strategy used by any other \term{function} in \clisp.
- For \term{objects} of \term{types} that \funref{equal} compares
- with \funref{eq}, item 3 requires that the \param{hash-code} be
- based on some immutable quality of the identity of the object.
- Another legitimate implementation technique would be to have
- \funref{sxhash} assign (and cache) a random hash code for these
- \term{objects}, since there is no requirement that \term{similar} but
- non-\funref{eq} objects have the same hash code.
- Although \term{similarity} is defined for \term{symbols} in terms
- of both the \term{symbol}'s \term{name} and the \term{packages} in which
- the \term{symbol} is \term{accessible}, item 3 disallows using \term{package}
- information to compute the hash code, since changes to the package status
- of a symbol are not visible to \param{equal}.
- \endissue{SXHASH-DEFINITION:SIMILAR-FOR-SXHASH}
- \endcom
|