Module Record


module Record: sig  end
The record collection.

A record is a collection of elements munished with a void topology (an element has no neighbors). The elements of a record are the values associated to the fields of the records.

A fields is any comparable MGS value, achieving the idea of a dictionary. However, the usual use of record is to use symbols as fields and this usage is supported by a special syntax and by type declarations. When all the fields of a records are symbol, they can be manipulated exactly like ordinary records in Pascal (or struct in C) with the fields denoted by simple identifiers.

The element of a record are acessed using the 'take function:

take(record, field)
returns the value associated with field in the record. This usage complies with the idea that the fields are the positions of a record.
record.(field)
is an infix syntax for take(record, field). If field is a symbol, says `id, then
record.id
abbreviates record.(`id) which is itself an abbreviation of take(record, `id)

One can defines record's type if all implied fields are symbols. A record declaration is introduced by the keyword record followed by the name of the type and by a record specification expression after an equal sign. Here is an example:

 record S = R + { a, b = ..., ~c } 
A record specification expression is a sum of record type names and record specification lists. In the previous example, R is the name of a record type which must have been previously declared, and { a, b = ..., ~c} is a record specification list. The idea is that the fields of R must be the fields specified in S augmented by the fields specified in the record specification list.

A record specification list is a list of record items specification separated by comma. A record item specification is either

The record types are in a subtyping relationships. For instance, the type {} is the most general record type. That is

record Rtop = {}
introduces the type Rtop which subsumes all others record type. In other word, if r is a record, then Rtop(r) always returns true. A simple field name a subsumes a type qualified name a:... and a value qualified name a=.... Type qualified names are incomparable, as well as value qualified names. For example, if we have
record R = {a};; record S = {a=0};; 
then for any record r such that S(r) holds, we have also R(r). Note that if a record type Q is defined as
record Q = ... + T + ... 
then Q is a subtype of T.

A record item can precise an item specification inherited through a recod type name. For example, in:

record R = {a};; record S = R + {a=3};; 
the record item a=3 makes in the specification of S, the definition of the fields a inherited from R more precise. If the specification are not compatible, an error is raised. In the example below, both S and R use incompatible field specification for a :
[record R = {a:int};; record S = R + {~a};; record T = R + {a:\x.false};;
(recall that type qualified name are incomparable).

A record type defioens a predicate with the same name. The predicate returns true if its argument is a record that fulfills all the record items specification of the type. NOTE that it can have additional fields as well.


 'dot : record -> string -> any
Computed record access. The expression dot(r, "xxx") returns r.xxx. Note that the second argument of the dot operator is a string (a value) while in the notation r.xxx the second argument is a syntactic identifier (not a value). This operator makes able to compute the field that you want access:

  dot({a1 = 1, a2 = 2, a3 = 3}, "a"+(3-2))
  
returns the value of the field a1 because "a"+(3-2) evaluates to "a1".
 'set_field : record -> string -> any -> record
Set the field of a record. 'set_field(r, "a", 0) creates or changes the value of the field a in record r. This change is applicative: a new record is created with the field a updated and returned. An equivalent form is r + {a=0} but 'set_field(r, "a", 0) enables the denotation of the fields records as strings. This function enables teh creation of fields with arbitrary name (including name not accepted in the dot notation).
 'remove_field : string -> record -> record
Remove the field of a record. 'remove_field("a", r) creates a new record similar to the record r except that there is no field a. If field a does not exists in r, the result is a copy of r.
Example :'remove_field("a",{x=1, a=2}) returns the (new) record {x=1}