Hashes

A Hash is a collection of unique keys and their corresponding values in pairs. 
	   In Smojo, the word 
# ( -- # )
creates an empty hash on the stack:
		# constant my-hash
		my-hash .
		{} ok
	
Here
constant
binds the hash created by
#
to
my-hash
. Therefore, we can get the hash directly by
my-hash
.

The word
#! ( k v # -- )
writes a key-value pair into an existing hash. It requires three arguments: key (k), value (v) and the target hash (#):
		"year" 2017 my-hash #!
		my-hash . 
		{year=2017} ok
	
Both the key and value can be anything -- text and integer ( as in the example above ) or XTs. Anything. The word
#@ ( k # -- v )
returns a matching value given its key:
		"year" my-hash #@ .
		2017 ok
	
Note that if the key is not on the hash, the result is a special object called
NULL ( -- null )
, which can be tested using the word
NULL? ( * -- f )
. For example:
		"bingo" my-hash #@ null? . 
		true ok
		"year" my-hash #@ null? .
		false ok 
	
You may test for the presence of a key-value pair on a hash by using the word
#CONTAINS? ( k # -- f )
. This word puts
TRUE
on the stack if a key exists on the hash and
FALSE
otherwise:
		"year" my-hash #contains? . 
		true ok
	
The word
#DROP ( k # -- )
removes a key-value pair from the hash; It requires two arguments: key and the target hash table:
		"year" my-hash #drop
		my-hash . 
		{} ok
	

In summary, hashes are a simple data structure in which you can store and retrieve data temporarily (i.e., as long as your program is running.). Here are some other useful words for a hash:
Word Action
#@ ( k # -- v )
Retrieves a value (v) from a hash given the corresponding key (k).
#! ( k v # -- )
Stores a key-value pair (k v) into a hash.
#CONTAINS? ( k # -- f )
Returns TRUE if the key (k) is on the hash and FALSE otherwise.
#KEYS ( # -- seq )
Takes a hash and returns the sequence of all keys. Note that the keys are returned in no particular order.
#VALUES ( # -- seq )
Takes a hash and returns the sequence of all values. Note that the values are returned in no particular order.
#SORTED ( -- # )
This puts a special "sorted" hash on the stack. The
#KEYS
of a sorted hash will be sorted in "alphabetical" (or more precisely, lexicographical) order.
># ( #t #s -- )
Copies the contents of the source hash (#s) into the target hash (#t).
#EMPTY? ( # -- f )
Returns
TRUE
if the hash is empty,
FALSE
otherwise.
#SIZE ( # -- n )
Returns the number of key-value pairs in the hash.

Quiz

Question 1

Is is possible to have 
NULL
as key or associated value in a hash? Prove your answer using a program.



Question 2

What happens if a key-value pair is overwritten by the same key but with a different value? Prove your answer using a program.



Question 3

Create a hash called "me" and write your name, age, and gender into the hash. Then try the following words on your hash:

		#SIZE       \ returns the number of key-value pairs in the hash.
		#EMPTY?     \ returns true if the hash is empty.
		#CONTAINS?  \ returns true if the has contains the given key
	
Continue with your hash "me", remove all the key-value pairs from hash "me" and then try
#EMPTY?
to see if it is empty now.



Question 4*

The words 
#KEYS
and
#VALUES
return the keys and the values in a hash as a sequence respectively. Write a word
#CLEAR
which removes all the key-value pairs in a hash. Hint: which word can remove key-value pairs from a hash and which word returns the required input for that word?



Question 5*

Can a hash be used as a value in a hash? When might this be useful? Hint: how would you store the details of each student (name, height, gender) in a class to be retrieved by that student's ID?



Next: Tuples