To illustrate other forms of name, consider the following declarations (given in skeletal, but hopefully self-explanatory form):
type PERSON(SEX : GENDER) is record BIRTH : DATE; ... SPOUSE : ... ; end record; subtype KING is PERSON(SEX => M); JOHN : KING; LOUIS : array (1 .. 18) of KING; |
The above declarations have defined several simple names: for example JOHN is the simple name of an object of subtype KING, and LOUIS is the simple name of an array of kings. Now, starting with simple names, we can form more complex names: a selected component such as
JOHN.SPOUSE
which denotes a component of the record object that is itself denoted by JOHN; and similarly an indexed component such as
LOUIS (9)
which denotes a particular component of our array of kings. We can also combine selected components and indexed components to form yet more complex names such as
LOUIS(15).SPOUSE
but not as in PL/1
LOUIS.SPOUSE(15)
Following Simula (and unlike Pascal), Ada allows function calls to be part of names. For example we can define a function HEIR as follows:
function HEIR(N : POSITIVE) return KING is begin if N < 18 then return LOUIS(N + 1); else raise LINEAGE_ERROR; end if; end; |
Now we can form names such as
HEIR(14).SPOUSE
which include function calls. Note that the function call HEIR(14) delivers a value (not a variable), so that the above name allows the SPOUSE component to be read, but not updated.
The ability to use function calls in names is especially useful when dealing with data structures constructed with access types. Thus an algorithm in a tree traversal may include names such as
NEXT(N).PART
where NEXT(N) delivers an access value, and where PART is a component of the object designated by the access value. In this case, reading and updating of the component PART are both possible.
This ability goes some way toward the principle of uniform referents advocated by Ross and others [Ro 70, GM 75]. Following this principle, Ada uses round brackets rather than square brackets for denoting array components, thereby unifying the syntax of indexed components and function calls. In the same spirit, the syntax of selected components is used for component selection of records, whether the records are statically or dynamically allocated (see 6.3.4).