Tables are mappings of key/value pairs. They contain a unique set of keys,
each of which maps to an arbitrary value. Any MOO value can be used as either
a key or a value.

Lists can be thought of as a special case of tables, where each element of the
list is bound to an integer key (the element's index) beginning with 1 up to
the number of elements in the list. Lists are not tables, however; the two are
not generally interchangeable.

Tables in LPMOO are sometimes known as mappings, associative arrays, or
dictionaries in other languages.

Tables are constructed with the following syntax:

  {key1 ~ value1, key2 ~ value2, ...}

@-splices may be used to insert the contents of another table into the one
being constructed. Where duplicate keys are found, only the first key and
value pair is kept. It is illegal to splice a list into a table, or vice
versa. Tables also may not be spliced as function arguments.

Values in tables may be looked up with `table[key]' syntax. If the specified
key is bound to the table, its associated value will be returned. Otherwise,
E_RANGE will be generated.

The `in' operator can be used to determine if a key is present in a table:
`key in table' returns 1 if and only if `key' is bound to `table'. This is
nearly the same as `key in tablekeys(table)' except that the former only
returns 0 or 1, and the latter is much less efficient.

The `for' language construct has been extended to accept a new syntax:

  for kvar ~ vvar in (table)
    ...
  endfor

This construct iterates over the given `table', with `kvar' assuming the value
of each key, and `vvar' assuming the value of each associated value in turn.

To test whether a value occurs as the value of any key in a table, use `value
in tablevalues(table)'. The returned index will either be 0 (does not occur),
or it will be an index you can use against tablekeys(table) to learn the
(first) key which maps to that value.

Tables can be altered directly with an indexed assignment: table[key] = value.
This has the same effect as: table = tableinsert(table, key, value).

N.B. Tables are immutable, just like all other MOO datatypes. No expression
can actually mutate an existing table; instead, a new table is generated and
returned with the desired mutation.

The following builtin functions manipulate tables:

tablemap(), tableinsert(), tabledelete(), tablekeys(), tablevalues()

Although any MOO value can be used as keys in a table, the use of lists and
other tables as keys is discouraged because they are inefficient. (They can,
however, be used as values in the table with no performance penalty.)

A new builtin variable, TABLE, can be used with the typeof() builtin function
to detect table values.