next up previous contents index
Next: Concrete implementations Up: Collections Previous: Adding and removing elements

Tables (mappings)

In table.cecil:


abstract object table[Key, Value] isa collection[Value]; 
extend type table[`Key,`Value] subtypes table[Key, `Value1 >= Value]; 
Tables map from keys to values (in other words, a table is a set of key/value pairs) such that a given key maps to at most one value. A table can be viewed as a collection of values, in some unspecified order. As such, operations like length, is_empty, do, pick_any, includes, find, copy, etc., are inherited from collection, and operate on the values part of the table.

A table is comparable if both its keys and values are comparable. Two tables are equal ( =) if they have the same set of keys and corresponding keys map to equal values.


signature do_associations(table[`Key,`Value], &(Key,Value):void):void; 
method do_associations_allowing_updates(t@:table[`Key,`Value], 
c:&(Key,Value):void):void;
method do(t@:table[`Key,`Value], c:&(Value):void):void; 
method do_allowing_updates(t@:table[`Key,`Value], 
c:&(Value):void):void;
method keys_do(t@:table[`Key,`Value], c:&(Key):void):void; 
method keys_do_allowing_updates(t@:table[`Key,`Value], c:&(Key):void):void; 
The control structure do_associations[_allowing_updates] forms the heart of a table, iterating through the keys and values of the table in pairs. The keys_do[_allowing_updates] methods iterate through just the keys.


signature fetch(table[`Key,`Value], key:Key, if_absent:&():Value):Value; 
implementation fetch(t@:table[`Key <= comparable[Key], `Value], key:Key, 
if_absent:&():Value):Value;
method fetch(t@:table[`Key,`Value], key:Key):Value; 
abstract object table_like[Key,Value]; 
signature fetch(table_like[`Key,`Value], Key):Value; 
method !(t@:table_like[`Key,`Value], key:Key):Value;
extend type table_like[`Key,`Value] subtypes table_like[Key, `Value1 >= Value]; 
extend table[`Key,`Value] isa table_like[Key,Value]; 
  The fetch methods support table lookup; the optional closure argument is invoked if the key isn't found. The infix ! operator can be used instead of fetch, e.g.:

t!n1 + t!n2


method find_key(t@:table[`Key,`Value <= comparable[Value]], value:Value):Key; 
method find_key(t@:table[`Key,`Value <= comparable[Value]], 
value:Value, if_absent:&():Key):Key;
method pick_any_key(t@:table[`Key,`Value]):Key; 
method pick_any_key(t@:table[`Key,`Value], if_empty:&():`T):Key|T; 
method includes_key(t@:table[`Key,`Value], key:Key):bool; 
method keys(t@:table[`Key,`Value]):collection[Key]; 
method keys_set(t@:table[`Key <= comparable[Key],`Value]):set[Key]; 
method keys_list(t@:table[`Key,`Value]):ordered_collection[Key]; 
extend table[`Key, `Value <= comparable[Value]] 
isa comparable[table[Key,Value]];
method =(t1@:table[`Key, `Value <= comparable[Value]], 
t2@:table[Key, Value]):bool;
method collection_name(@:table[`Key,`Value]):string; 
method values_print_string(t@:table[`Key,`Value]):string; 
method elems_print_string(t@:table[`Key,`Value]):string; 
method elems_print(t@:table[`Key,`Value]):void; 
The find_key method does reverse table lookup: given a value, find a key that maps to that value. The includes_key method tests whether a key is defined, and the keys[_{set,list}] operations return the collection of keys in the table.


abstract object i_table[Key, Value] isa table[Key, Value]; 
extend type i_table[`Key, `Value] subtypes i_table[Key, `Value1 >= Value]; 
method copy(t@:`T <= i_table[`Key,`Value]):T; 
Tables are refined into immutable and mutable varieties. An i_table is immutable.


abstract object m_table[Key, Value] isa table[Key, Value]; 
signature store(m_table[`Key,`Value], key:Key, value:Value, 
if_absent:&():void):void;
method store(t@:m_table[`Key,`Value], key:Key, value:Value):void; 
method store_no_dup(t@:m_table[`Key,`Value], key:Key, value:Value):void; 
abstract object m_table_like[Key,Value] isa table_like[Key,Value]; 
signature store(m_table_like[`Key,`Value], Key, Value):void; 
method set_!(t@:m_table_like[`Key,`Value], key:Key, value:Value):void;
extend m_table[`Key,`Value] isa m_table_like[Key,Value]; 
  An m_table supports changing bindings of keys to values through the store or set_! method, but not necessarily adding new keys or removing old ones. (See removable_table for operations for removing keys from tables.)


method fetch_or_init(t@:m_table[`Key,`Value], key:Key, 
if_init:&():Value):Value;
method copy(t@:m_table[`Key,`Value]):m_table[Key,Value]; 
signature copy_empty(m_table[`Key,`Value]):m_table[Key,Value]; 
An m_table also supports fetch_or_init, a variation of fetch that, if the key is not found, computes and adds a default value to the table and returns that value; fetch_or_init abstracts a very common table-manipulation idiom. Method copy_empty, given a (mutable) table, returns idiom. Method copy_empty, given a (mutable) table, returns an empty mutable table of the same kind.


abstract object removable_table[Key, Value] isa table[Key, Value]; 
extend type removable_table[`Key,`Value] 
subtypes removable_table[Key, `Value1 >= Value];
signature remove_key(removable_table[`Key,`Value], key:Key, 
if_absent:&():`Value):Value;
method remove_key(t@:removable_table[`Key,`Value], key:Key):Value; 
method remove_all(t@:removable_table[`Key,`Value]):void; 
method remove_keys_if(t@:removable_table[`Key,`Value], 
pred:&(Key):bool):int;
method remove_if(t@:removable_table[`Key,`Value], 
pred:&(Value):bool):int;
signature copy_empty(removable_table[`Key,`Value]):removable_table[Key,Value]; 
A removable_table supports removing bindings from the table, given the key to remove. (A table that inherits from removable_collection, on the other hand, supports removing bindings from the table, given the value.)


abstract object m_removable_table[Key, Value] 
isa m_table[Key, Value], removable_table[Key, Value];
signature copy(m_removable_table[`Key,`Value]):m_removable_table[Key,Value]; 
signature copy_empty(m_removable_table[`Key,`Value] 
):m_removable_table[Key,Value];
m_removable_table is the commonly used kind of table, which supports addition, removal, and modification of key-to-value bindings. Both addition and modification of bindings is done via store or set_!. (For non-table collections, addition of elements is done via add methods.) The set_! method can be invoked using the assignment message sugar:

t ! key := value;
Removal of bindings is done via the inherited remove_key et al. methods.



 
next up previous contents index
Next: Concrete implementations Up: Collections Previous: Adding and removing elements

The Cecil project