{ $contract "Outputs the hashcode of the object. The fundamental invariant that must never be violated is that if two objects are equal under " { $link = } ", they must have the same hashcode." }
{ $notes "If mutable objects are used as hashtable keys, they must not be mutated in such a way that their hashcode changes. Doing so will violate bucket sorting invariants and result in undefined behavior." } ;
{ $values { "key" "a key" } { "array" "the underlying array of a hashtable" } { "i" "the index to begin hashtable search" } }
{ $description "Computes the index to begin searching from the hashcode of the key. Always outputs an even value since keys are stored at even indices of the underlying array." } ;
HELP: probe "( array i -- array i )"
{ $values { "array" "the underlying array of a hashtable" } { "i" "a search index" } }
{ $description "Outputs the next hashtable search index." } ;
HELP: key@ "( key hash -- i )"
{ $values { "key" "a key" } { "hash" "a hashtable" } { "i" "the index of the key, or -1 if it is not present" } }
{ $description "Searches the hashtable for the key using a linear probing strategy. Searches stop if either the key or an " { $link ((empty)) } " sentinel is found. Searches skip the " { $link ((tombstone)) } " sentinel." }
{ $see-also new-key@ } ;
HELP: new-key@ "( key hash -- i )"
{ $values { "key" "a key" } { "hash" "a hashtable" } { "i" "the index where the key would be stored" } }
{ $description "Searches the hashtable for the key using a linear probing strategy. If the key is not present in the hashtable, outputs the index where it should be stored." }
{ $see-also new-key@ } ;
HELP: if-key "( key hash true false -- )"
{ $values { "key" "a key" } { "hash" "a hashtable" } { "true" "a quotation to call if the key is found, with stack effect " { $snippet "( true: index key hash -- )" } } { "false" "a quotation to call if the key is not found" } }
{ $description "Searches the hashtable for the key, calling one of the two quotations depending on the outcome." } ;
HELP: nth-pair "( n seq -- key value )"
{ $values { "n" "an index in the sequence" } { "seq" "a sequence" } { "key" "the first element of the pair" } { "value" "the second element of the pair" } }
{ $description "Fetches the elements with index " { $snippet "n" } " and " { $snippet "n+1" } ", respectively." }
{ $values { "key" "the first element of the pair" } { "value" "the second element of the pair" } { "n" "an index in the sequence" } { "seq" "a sequence" } }
{ $description "Stores a pair of values into the elements with index " { $snippet "n" } " and " { $snippet "n+1" } ", respectively." }
{ $warning "This word is in the " { $vocab-link "hashtables-internals" } " vocabulary because passing an array of odd length can lead to memory corruption." } ;
{ $values { "array" "an array of pairs" } { "quot" "a quotation with stack effect " { $snippet "( key value -- ? )" } } { "?" "conjunction of quotation outputs" } }
{ $description "Applies a predicate quotation to successive pairs in the array, and outputs true if the array is empty or if the quotation yields true for each pair." }
{ $warning "This word is in the " { $vocab-link "hashtables-internals" } " vocabulary because passing an array of odd length can lead to memory corruption." } ;
{ $description "Stores the key/value pair into the hashtable. This word does not grow the hashtable if it exceeds capacity, therefore a hang can result. User code should use " { $link set-hash } " instead, which grows the hashtable if necessary." }
{ $description "User code should not call this word. It is unsafe and only used in the implementation of " { $link hash-keys } " and " { $link hash-values } ", both of which are safe." }
{ $warning "This word is in the " { $vocab-link "hashtables-internals" } " vocabulary because passing an invalid value for " { $snippet "i" } " can lead to memory corruption." } ;
{ $values { "hash" "a hashtable" } { "n" "a non-negative integer" } }
{ $description "Outputs the number of entries stored in the hashtable." } ;
HELP: hash-empty? "( hash -- ? )"
{ $values { "hash" "a hashtable" } { "?" "a boolean" } }
{ $description "Tests if the hashtable does not contain any entries." } ;
HELP: hash* "( key hash -- value ? )"
{ $values { "key" "an object to look up in the hashtable" } { "hash" "a hashtable" } { "value" "the value associated to the key, or " { $link f } " if the key is not present in the hashtable" } { "?" "a boolean indicating if the key was present" } }
{ $description "Looks up the value associated with a key. The boolean flag can decide between the case of a missing value, and a value of " { $link f } "." }
{ $values { "key" "an object to look up in the hashtable" } { "hash" "a hashtable" } }
{ $description "Tests if the hashtable contains a key/value pair whose key is equal to the given key." }
{ $see-also hash hash* ?hash ?hash* } ;
HELP: ?hash* "( key hashtable/f -- ? )"
{ $values { "key" "an object to look up in the hashtable" } { "hash/f" "a hashtable or " { $link f } } }
{ $description "A variant of " { $link hash* } " overloaded to return " { $link f } " if the given mapping is " { $link f } "." }
{ $see-also hash-member? hash hash* ?hash } ;
HELP: hash "( key hash -- value )"
{ $values { "key" "an object to look up in the hashtable" } { "hash" "a hashtable" } { "value" "the value associated to the key, or " { $link f } " if the key is not present in the hashtable" } }
{ $values { "key" "an object to look up in the hashtable" } { "hash/f" "a hashtable or " { $link f } } { "value" "the value associated to the key, or " { $link f } " if the key is not present in the hashtable" } }
{ $description "A variant of " { $link hash } " overloaded to return " { $link f } " if the given mapping is " { $link f } "." }
{ $values { "hash" "a hashtable" } { "keys" "an array of keys" } }
{ $description "Outputs an array of all keys in the hashtable." }
{ $see-also hash-values hash>alist alist>hash } ;
HELP: hash-values "( hash -- keys )"
{ $values { "hash" "a hashtable" } { "values" "an array of values" } }
{ $description "Outputs an array of all values in the hashtable." }
{ $see-also hash-keys hash>alist alist>hash } ;
HELP: hash>alist "( hash -- alist )"
{ $values { "hash" "a hashtable" } { "alist" "an array of key/value pairs" } }
{ $description "Outputs an array of all key/value pairs in the hashtable. Each pair is itself a two-element array." }
{ $see-also hash-keys hash-values alist>hash } ;
HELP: alist>hash "( alist -- hash )"
{ $values { "alist" "a sequence of key/value pairs" } { "hash" "a hashtable" } }
{ $description "Constructs a hashtable from a sequence of key/value pairs, where each pair is a two-element sequence. In the case of duplicate keys, later pairs take precedence." }
{ $see-also hash-keys hash-values hash>alist } ;
HELP: hash-each "( hash quot -- )"
{ $values { "hash" "a hashtable" } { "quot" "a quotation with stack effect " { $snippet "( key value -- )" } } }
{ $description "Applies a predicate quotation to each key/value pair in the hashtable. Outputs true if the hashtable is empty or the quotation yields true for each entry." } ;
HELP: hash-all-with? "( obj hash quot -- )"
{ $values { "obj" "an object" } { "hash" "a hashtable" } { "quot" "a quotation with stack effect " { $snippet "( obj key value -- ? )" } } { "?" "a boolean" } }
{ $description "Variant of " { $link hash-all? } " which pushes a retained object on each invocation of the quotation." } ;
{ $values { "hash1" "a hashtable" } { "hash2" "a hashtable" } { "?" "a new hashtable" } }
{ $description "Tests if " { $snippet "hash2" } " contains all key/value pairs of " { $snippet "hash1" } "." } ;
HELP: hash-stack "( key seq -- value )"
{ $values { "key" "a key" } { "seq" "a sequence of hashtables" } { "value" "a value or " { $link f } } }
{ $description "Looks up the key in every hashtable in the sequence, search from back to front. If the key could not be found, outputs " { $link f } ". This word is used to implement abstractions such as nested scopes; if the sequence is a stack represented by a vector, then the most recently pushed hashtable -- the innermost scope -- will be searched first." } ;
{ $values { "hash1" "a hashtable" } { "hash2" "a hashtable" } { "intersection" "a new hashtable" } }
{ $description "Constructs a hashstable consisting of all key/value pairs from " { $snippet "hash2" } " such that the key is also present in " { $snippet "hash1" } "." }
{ $notes "The values of the keys in " { $snippet "hash1" } " are disregarded, so this word is usually used for set-theoretic calculations where the hashtable in question either has dummy sentinels as values, or the values equal the keys." } ;
HELP: hash-diff "( hash1 hash2 -- difference )"
{ $values { "hash1" "a hashtable" } { "hash2" "a hashtable" } { "difference" "a new hashtable" } }
{ $description "Constructs a hashstable consisting of all key/value pairs from " { $snippet "hash2" } " such that the key is not present in " { $snippet "hash1" } "" }
{ $notes "The values of the keys in " { $snippet "hash1" } " are disregarded, so this word is usually used for set-theoretic calculations where the hashtable in question either has dummy sentinels as values, or the values equal the keys." } ;
HELP: hash-update "( hash1 hash2 -- )"
{ $values { "hash1" "a hashtable" } { "hash2" "a hashtable" } }
{ $values { "seq" "a sequence of hashtables" } { "hash" "a new hashtable" } }
{ $description "Constructs a hashtable by merging every element of the sequence, with key/value pairs in subsequent hashtables taking precedence." } ;
HELP: hash-union "( hash1 hash2 -- union )"
{ $values { "hash1" "a hashtable" } { "hash2" "a hashtable" } { "union" "a new hashtable" } }
{ $description "Constructs a hashstable consisting of all key/value pairs from " { $snippet "hash1" } " and " { $snippet "hash2" } ", with entries from " { $snippet "hash2" } " taking precedence." }
{ $notes "The values of the keys in " { $snippet "hash1" } " are disregarded, so this word is usually used for set-theoretic calculations where the hashtable in question either has dummy sentinels as values, or the values equal the keys." } ;
HELP: remove-all "( hash seq -- subseq )"
{ $values { "hash" "a hashtable" } { "seq" "a sequence" } { "subseq" "a new sequence" } }
{ $description "Constructs a sequence consisting of all elements from the sequence that appear as keys in the hashtable." }
{ $notes "The values of the keys in the hashtable are disregarded, so this word is usually used for set-theoretic calculations where the hashtable in question either has dummy sentinels as values, or the values equal the keys." } ;
HELP: cache "( key hash quot -- value )"
{ $values { "key" "a key" } { "hash" "a hashtable" } { "quot" "a quotation with stack effect " { $snippet "( key -- value )" } } { "value" "a previously-retained or freshly-computed value" } }
{ $description "If the key is present in the hashtable, outputs the associated value, otherwise calls the quotation to produce a value and stores the key/value pair into the hashtable." }
{ $values { "seq" "a sequence" } { "quot" "a quotation with stack effect " { $snippet "( key -- value )" } } { "hash" "a hashtable" } { "value" "a previously-retained or freshly-computed value" } }
{ $description "Applies the quotation to each element of the sequence to produce a value corresponding to each key, and constructs a new hashtable from these key/value pairs." } ;