Previous | Table of Contents | Next |
I am the voice of today, the herald of tomorrow. I am the leaden army that conquers the worldI am TYPE.
Frederic William Goudy
Modula-3 uses structural equivalence, instead of the name equivalence of Modula-2. Two types are the same if their definitions become the same when expandedthat is, when all constant expressions are replaced by their values and all type names are replaced by their definitions. In the case of recursive types, the expansion is the infinite limit of the partial expansions. A type expression is generally allowed wherever a type is required.
A type is empty if it contains no values. For example, [1..0] is an empty type. Empty types can be used to build non-empty types (for example, SET OF [1..0], which is not empty because it contains the empty set). It is a static error to declare a variable of an empty type.
Every expression has a statically determined type, which contains every value that the expression can produce. The type of a designator is the type of the variable it produces.
Assignability and type compatibility are defined in terms of a single syntactically specified subtype relation with the property that if T is a subtype of U, then every member of T is a member of U. The subtype relation is reflexive and transitive.
Every expression has a unique type, but a value can be a member of many types. For example, the value 6 is a member of both [0..9] and INTEGER. It would be ambiguous to talk about the type of a value. Thus the phrase type of x means type of the expression x, whereas x is a member of T means the value of x is a member of T.
However, there is one sense in which a value can be said to have a type: Every object or traced reference value includes a code for a type, called the allocated type of the reference value. The allocated type is tested by TYPECASE. The type constructors and subtyping rules are discussed later in the chapter.
There are three kinds of ordinal types: enumerations, subranges, and INTEGER. An enumeration type is declared like this:
TYPE T = {id1, id2, ..., idn}
where the ids are distinct identifiers. The type T is an ordered set of n values; the expression T.idi denotes the ith value of the type in increasing order. The empty enumeration {} is allowed.
Integers and enumeration elements are collectively called ordinal values. The base type of an ordinal value v is INTEGER if v is an integer; otherwise, it is the unique enumeration type that contains v.
A subrange type is declared like this:
TYPE T = [Lo..Hi]
where Lo and Hi are two ordinal values with the same base type, called the base type of the subrange. The values of T are all the values from Lo to Hi inclusive. Lo and Hi must be constant expressions. If Lo exceeds Hi, the subrange is empty.
The operators ORD and VAL convert between enumerations and integers. The VAL convert, LAST, and NUMBER applied to an ordinal type return the first element, last element, and number of elements.
Here are the predeclared ordinal types:
INTEGER | All integers represented by the implementation | |
CARDINAL | Behaves just like the subrange [0..LAST(INTEGER)] | |
BOOLEAN | The enumeration {FALSE, TRUE} | |
CHAR | An enumeration containing at least 256 elements |
The first 256 elements of type CHAR represent characters in the ISO-Latin-1 code, which is an extension of ASCII. The language does not specify the names of the elements of the CHAR enumeration. The syntax for character literals is specified in the section on literals. FALSE and TRUE are predeclared synonyms for BOOLEAN.FALSE and BOOLEAN.TRUE.
Each distinct enumeration type introduces a new collection of values, but a subrange type reuses the values from the underlying type:
TYPE T1 = {A, B, C}; T2 = {A, B, C}; U1 = [T1.A..T1.C]; U2 = [T1.A..T2.C]; (* error *) V = {A, B}
T1 and T2 are the same type because they have the same expanded definition. In particular, T1.C equals T2.C and therefore U1 and U2 are also the same type. But the types T1 and U1 are distinct, although they contain the same values, because the expanded definition of T1 is an enumeration whereas the expanded definition of U1 is a subrange. The type V is a third type whose values V.A and V.B are not related to the values T1.A and T1.B.
There are three floating-point types, which in order of increasing range and precision are REAL, LONGREAL, and EXTENDED. The properties of these types are specified by required interfaces.
Previous | Table of Contents | Next |