Record is a built-in type in RESOLVE/C++, which is included when you bring "RESOLVE_Foundation.h" into the global context. The name Record is therefore unusual: It is the name of a concrete template even though it does not end in "_2" or "_1a" or the like.
The programming type Record allows you to set up and access the individual objects in a small, fixed-size (no larger than ten) collection of objects of various and arbitrary types. You should consider Record whenever you want to treat such a collection of diverse objects as a single object for some purposes, and as individual constituent sub-objects for other purposes. The way you achieve the former behavior is straightforward, since this is what an "object" ordinarily is. The way you achieve the latter behavior simultaneously is to give symbolic names (called field names) to the sub-objects (also called fields) of a Record object. By using these field names with accessor operations, you can directly manipulate the fields of a Record object. In fact, this is the only way to manipulate the sub-objects.
The mathematical model of a Record, then, is just a tuple whose members are the Record fields. A convienent way to depict a Record object is to make a fixed-size table with two columns and as many rows as there are fields. In the left column of a row is a field name, which is the same for all objects of the same Record type. The right column is the value of the sub-object with that field name, which is (generally) different among different objects of the same Record type.
Let's consider an example. Suppose you want to keep track of the following information for each employee of a company: first name, middle name, last name, address, and salary. For some purposes you want all the information about a particular employee to stay together (e.g., perhaps you want a Sequence whose Items are this Record type; or you want this Record type to be the R-Item in a Partial_Map, with the employee's ID number as the D_Item). For other purposes you want to be able to get to the individual pieces of informatio about a particular employee (e.g., perhaps you want to give the employee a raise).
There are several ways to use Record to do this. Here are two approaches:
| "Employee" field name | field (sub-object) value |
| first_name | "John" |
| middle_name | "Q." |
| last_name | "Doe" |
| Address | "123 Easy St." |
| Salary | 85600 |
The mathematical model of this value is a five-tuple:
("John", "Q.", "Doe", "123 Easy St.", 85600)
| "Full_Name" field name | field (sub-object) value |
| first_name | "John" |
| middle_name | "Q." |
| last_name | "Doe" |
| "Employee" field name | field (sub-object) value |
| name | ("John", "Q.", "Doe") |
| Address | "123 Easy St." |
| Salary | 85600 |
The mathematical model of this value is a three-tuple whose first component is another three-tuple:
(("John", "Q.", "Doe"), "123 Easy St.", 85600)
The first approach gives a “flat” Record with five fields and no further organization. The second approach — probably the better one from the standpoint of human understanding — gives a more “structured” Record, one of whose fields is itself a Record that is meaningful even outside the context of employee information. In fact, in practice you probably would need more detailed address information. So you’d also want to subdivide the address into street address, city, etc., by making a concrete_instance class Address as an instance of concrete_template class Record in much the same fashion as Full_Name above.
On the other hand, suppose you also wanted to keep track of each employee’s birthdate. This suggests another concrete_instance class Date — which also would be generally useful outside this application. The mathematical model of Date probably should be a three-tuple of integers with some constraints on the values of the fields. However, Date should not simply be a Record instance because there also are mutual constraints on the values of the fields. That is, the day must be between 1 and 31 inclusive if the month is 1, but between 1 and 28 inclusive if the month is 2 (except if the year is a leap year, in which case 1 through 29 is allowed), and so on. The complication introduced by such a constraint is a clue that it is inappropriate to treat a date as merely three independent numbers which are placed together for convenience — which is how you’d be treating it if you made Date an instance of a Record implementation.
You can guess from the above description that Record is a very unusual template component in the sense that different instantiations of it involve different numbers of template parameters! Indeed this is so, for here are the actual RESOLVE/C++ statements that declare the concrete_instance classes and their field names for the second approach above:
concrete_instance
class Full_Name :
instantiates
Record <
Text,
Text,
Text,
number_of_fields (3)
>
{};
field_name (Full_Name, 0, Text, first_name);
field_name (Full_Name, 1, Text, middle_name);
field_name (Full_Name, 2, Text, last_name);
concrete_instance
class Employee :
instantiates
Record <
Full_Name,
Text,
Integer,
number_of_fields (3)
>
{};
field_name (Employee, 0, Full_Name, name);
field_name (Employee, 1, Text, address);
field_name (Employee, 2, Integer, salary);
A closely related component is Array. The most important difference is that the individual objects in a Record may be of different types; while all the individual objects in an Array — and in most other collections of objects — must be of the same type. However, a Record can contain at most ten fields, and the number of fields is fixed at instantiation time; while an Array may contain arbitrarily many objects and its size is determined at run-time by calling the Set_Bounds operation.
One other component is closely related to Record. It is essentially identical to Record — except that its name is Representation — and it is used for one and only one thing in RESOLVE/C++ programs: If you are implementing a kernel abstraction, then you always collect together the individual objects that you are using to represent an object of the new type, and make them fields of an instance of Representation. Client programmers need to know nothing about Representation except that (a) it is essentially Record with a different name, and (b) it shouldn’t be used in ordinary client programs.
Abstract Components
Concrete Components
To bring this component into the context you write:
#include "RESOLVE_Foundation.h"
