3.2 Types and Subtypes
Static Semantics
1
{type}
{primitive operation
[partial]} A
type is characterized
by a set of values, and a set of
primitive operations which implement
the fundamental aspects of its semantics.
{object
[partial]} An
object of a given type
is a run-time entity that contains (has) a value of the type.
1.a/2
Glossary entry: {
Type} Each object
has a type. A
type has an associated set of values, and a set
of
primitive operations which implement the fundamental aspects
of its semantics. Types are grouped into
categories classes.
Most language-defined categories of types are also
classes of types The types of a given
class share a set of primitive operations. {closed under derivation}
Classes are closed under derivation; that is, if
a type is in a class, then all of its derivatives are in that class.
1.b/2
Glossary entry: {Subtype} A subtype
is a type together with a constraint or null exclusion,
which constrains the values of the subtype to satisfy a certain condition.
The values of a subtype are a subset of the values of its type.
2/2
{
AI95-00442-01}
{category (of types)}
{class (of
types)} Types are grouped into
categories classes
of types
, reflecting the similarity of their values
and primitive operations.
{language-defined
class (of types)} There exist several
language-defined categories classes
of types (see NOTES below)
, reflecting the similarity
of their values and primitive operations.
{language-defined
category (of types)} [Most categories
of types form classes of types.] {elementary
type} Elementary types are those
whose values are logically indivisible;
{composite
type} {component}
composite types are those whose values are
composed of
component values.
{aggregate:
See also composite type}
2.a/2
Proof: {
AI95-00442-01}
The formal definition of category and class
is found in 3.4.
2.b/2
Glossary entry: {
Class (of types)}
{
closed under derivation}
A class is a set
of types that is closed under derivation, which means that if a given
type is in the class, then all types derived from that type are also
in the class. The set of types of a class share common properties, such
as their primitive operations.
2.b.1/2
Glossary entry: {Category
(of types)} A category of types is a set of types with one or more
common properties, such as primitive operations. A category of types
that is closed under derivation is also known as a class.
2.c
Glossary entry: {Elementary type}
An elementary type does not have components.
2.d/2
Glossary entry: {Composite type}
A composite type may have has
components.
2.e
Glossary entry: {Scalar type}
A scalar type is either a discrete type or a real type.
2.f
Glossary entry: {Access type}
An access type has values that designate aliased objects. Access types
correspond to “pointer types” or “reference types”
in some other languages.
2.g
Glossary entry: {Discrete type}
A discrete type is either an integer type or an enumeration type. Discrete
types may be used, for example, in case_statements
and as array indices.
2.h
Glossary entry: {Real type} A
real type has values that are approximations of the real numbers. Floating
point and fixed point types are real types.
2.i
Glossary entry: {Integer type}
Integer types comprise the signed integer types and the modular types.
A signed integer type has a base range that includes both positive and
negative numbers, and has operations that may raise an exception when
the result is outside the base range. A modular type has a base range
whose lower bound is zero, and has operations with “wraparound”
semantics. Modular types subsume what are called “unsigned types”
in some other languages.
2.j
Glossary entry: {Enumeration type}
An enumeration type is defined by an enumeration of its values, which
may be named by identifiers or character literals.
2.k
Glossary entry: {Character type}
A character type is an enumeration type whose values include characters.
2.l
Glossary entry: {Record type}
A record type is a composite type consisting of zero or more named components,
possibly of different types.
2.m
Glossary entry: {Record extension}
A record extension is a type that extends another type by adding additional
components.
2.n
Glossary entry: {Array type} An
array type is a composite type whose components are all of the same type.
Components are selected by indexing.
2.o/2
Glossary entry: {Task type} A
task type is a composite type used to represent whose
values are tasks, which are active entities which that
may execute concurrently and which can communicate
via queued task entries with other tasks.
The top-level task of a partition is called the environment task.
2.p/2
Glossary entry: {Protected type}
A protected type is a composite type whose components are accessible
only through one of its protected operations which synchronize protected
from concurrent access by multiple tasks.
2.q/2
Glossary entry: {Private type}
A private type gives a is
a partial view of a type that reveals only
some of its properties. The remaining properties are provided by the whose
full view given elsewhere. Private types can be
used for defining abstractions that hide unnecessary details hidden
from its clients.
2.r/2
Glossary entry: {Private extension}
A private extension is a type that extends another
type, with the additional properties like
a record extension, except that the components of the extension part
are hidden from its clients.
2.s/2
Glossary entry: {Incomplete
type} An incomplete type gives a view of a type that reveals only
some of its properties. The remaining properties are provided by the
full view given elsewhere. Incomplete types can be used for defining
recursive data structures.
3
{scalar type}
The elementary types are the
scalar types
(
discrete and
real) and the
access types (whose
values provide access to objects or subprograms).
{discrete
type} {enumeration
type} Discrete types are either
integer
types or are defined by enumeration of their values (
enumeration
types).
{real type} Real
types are either
floating point types or
fixed point types.
4/2
{
AI95-00251-01}
{
AI95-00326-01}
The composite types are the
record types,
record extensions,
array types,
interface types, task
types, and
protected types.
{private
type} {private
extension} A private type or private
extension represents a partial view (see 7.3)
of a type, providing support for data abstraction. A partial view is
a composite type.
4.a/2
This paragraph
was deleted.To be honest: {
AI95-00442-01}
The set of all record types do not form a class
(because tagged record types can have private extensions), though the
set of untagged record types do. In any case, what record types had in
common in Ada 83 (component selection) is now a property of the composite
class, since all composite types (other than array types) can have discriminants.
Similarly, the set of all private types do not form a class (because
tagged private types can have record extensions), though the set of untagged
private types do. Nevertheless, the set of untagged private types is
not particularly “interesting” — more interesting is
the set of all nonlimited types, since that is what a generic formal
(nonlimited) private type matches.
4.1/2
{
AI95-00326-01}
{incomplete type}
{private type}
{private extension}
There can be multiple views of a type with varying
sets of operations. [An incomplete type represents an incomplete
view (see 3.10.1) of a type with a very
restricted usage, providing support for recursive data structures. A
private type or private extension represents a partial
view (see 7.3) of a type, providing support
for data abstraction. The full view (see 3.2.1)
of a type represents its complete definition.] An incomplete or partial
view is considered a composite type[, even if the full view is not].
4.b/2
Proof: The real
definitions of the views are in the referenced clauses.
5/2
{
AI95-00326-01}
{discriminant} Certain
composite types (and
partial views thereof)
have special components called
discriminants whose values affect
the presence, constraints, or initialization of other components. Discriminants
can be thought of as parameters of the type.
6/2
{
AI95-00366-01}
{subcomponent} The
term
subcomponent is used in this International Standard in place
of the term component to indicate either a component, or a component
of another subcomponent. Where other subcomponents are excluded, the
term component is used instead.
{part
(of an object or value)} Similarly, a
part of an object or value is used to mean the whole object or
value, or any set of its subcomponents.
The terms
component, subcomponent, and part are also applied to a type meaning
the component, subcomponent, or part of objects and values of the type.
6.a
Discussion: The definition of “part”
here is designed to simplify rules elsewhere. By design, the intuitive
meaning of “part” will convey the correct result to the casual
reader, while this formalistic definition will answer the concern of
the compiler-writer.
6.b
We use the term “part” when talking
about the parent part, ancestor part, or extension part of a type extension.
In contexts such as these, the part might represent an empty set of subcomponents
(e.g. in a null record extension, or a nonnull extension of a null record).
We also use “part” when specifying rules such as those that
apply to an object with a “controlled part” meaning that
it applies if the object as a whole is controlled, or any subcomponent
is.
7/2
{
AI95-00231-01}
{constraint [partial]} The
set of possible values for an object of a given type can be subjected
to a condition that is called a
constraint {null
constraint} (the case of a
null constraint
that specifies no restriction is also included)[; the rules for which
values satisfy a given kind of constraint are given in
3.5
for
range_constraints,
3.6.1
for
index_constraints, and
3.7.1
for
discriminant_constraints].
The set of possible values for an object of an access type can also be
subjected to a condition that excludes the null value (see 3.10).
8/2
{
AI95-00231-01}
{
AI95-00415-01}
{subtype} A
subtype of a given type is a combination of the type, a constraint
on values of the type, and certain attributes specific to the subtype.
The given type is called the
type of the subtype type
of the subtype.
{type
(of a subtype)} {subtype
(type of)} Similarly, the associated
constraint is called the
constraint of the subtype constraint
of the subtype.
{constraint
(of a subtype)} {subtype
(constraint of)} The set of values
of a subtype consists of the values of its type that satisfy its constraint
and any exclusion of the null value.
{belong
(to a subtype)} Such values
belong
to the subtype.
{values
(belonging to a subtype)} {subtype
(values belonging to)}
8.a
Discussion: We make a strong distinction
between a type and its subtypes. In particular, a type is not
a subtype of itself. There is no constraint associated with a type (not
even a null one), and type-related attributes are distinct from subtype-specific
attributes.
8.b
Discussion: We no longer use the term
"base type." All types were "base types" anyway in
Ada 83, so the term was redundant, and occasionally confusing. In the
RM95 we say simply "the type of the subtype" instead
of "the base type of the subtype."
8.c
Ramification: The value subset for a
subtype might be empty, and need not be a proper subset.
8.d/2
To be honest: {
AI95-00442-01}
Any name of a
category class
of types (such as “discrete”
, or “real”
, or),
or other category of types (such as “limited”
or “incomplete”) is also used to qualify its subtypes,
as well as its objects, values, declarations, and definitions, such as
an “integer type declaration” or an “integer value.”
In addition, if a term such as “parent subtype” or “index
subtype” is defined, then the corresponding term for the type of
the subtype is “parent type” or “index type.”
8.e
Discussion: We use these corresponding
terms without explicitly defining them, when the meaning is obvious.
9
{constrained}
{unconstrained}
{constrained (subtype)}
{unconstrained (subtype)}
A subtype is called an
unconstrained subtype
if its type has unknown discriminants, or if its type allows range, index,
or discriminant constraints, but the subtype does not impose such a constraint;
otherwise, the subtype is called a
constrained subtype (since
it has no unconstrained characteristics).
9.a
Discussion: In an earlier version of
Ada 9X, "constrained" meant "has a non-null constraint."
However, we changed to this definition since we kept having to special
case composite non-array/non-discriminated types. It also corresponds
better to the (now obsolescent) attribute 'Constrained.
9.b
For scalar types, “constrained”
means “has a non-null constraint”. For composite types, in
implementation terms, “constrained” means that the size of
all objects of the subtype is the same, assuming a typical implementation
model.
9.c
Class-wide subtypes are always unconstrained.
10/2
2 {
AI95-00442-01}
Any set of types can be called a “category”
of types, and any Any set of types
that is closed under derivation (see
3.4) can
be called a “class” of types. However, only certain
categories
and classes are used in the description of the rules of the language
— generally those that have their own particular set of primitive
operations (see
3.2.3), or that correspond
to a set of types that are matched by a given kind of generic formal
type (see
12.5).
{language-defined
class [partial]} The following are examples
of “interesting”
language-defined classes: elementary,
scalar, discrete, enumeration, character, boolean, integer, signed integer,
modular, real, floating point, fixed point, ordinary fixed point, decimal
fixed point, numeric, access, access-to-object, access-to-subprogram,
composite, array, string, (untagged) record, tagged, task, protected,
nonlimited. Special syntax is provided to define types in each of these
classes.
In addition to these classes, the following
are examples of “interesting” language-defined categories:
{language-defined categories [partial]}
abstract, incomplete, interface, limited, private,
record.
10.a
Discussion: {
value}
A
value is a run-time entity with a given type which can be assigned
to an object of an appropriate subtype of the type. {
operation}
An
operation is a program entity that operates
on zero or more operands to produce an effect, or yield a result, or
both.
10.b/2
Ramification: {
AI95-00442-01}
Note that a type's
category (and class
)
depends on the place of the reference — a private type is composite
outside and possibly elementary inside. It's really the
view that
is elementary or composite. Note that although private types are composite,
there are some properties that depend on the corresponding full view
— for example, parameter passing modes, and the constraint checks
that apply in various places.
10.c/2
{
AI95-00345-01}
{
AI95-00442-01}
Every property of types forms a category, but not Not
every property of types represents a class. For example, the set of all
abstract types does not form a class, because this set is not closed
under derivation.
Similarly, the set of all interface
types does not form a class.
10.d/2
{
AI95-00442-01}
The set of limited types
does not form a class
(since nonlimited types can inherit from limited interfaces), but the
set of nonlimited types does. The set of tagged record types and the
set of tagged private types do not form a class (because each of them
can be extended to create a type of the other category); that implies
that the set of record types and the set of private types also do not
form a class (even though untagged record types and untagged private
types do form a class). In all of these cases, we can talk about the
category of the type; for instance, we can talk about the “category
of limited types”. forms a class in
the sense that it is closed under derivation, but the more interesting
class, from the point of generic formal type matching, is the set of
all types, limited and nonlimited, since that is what matches a generic
formal “limited” private type. Note also that a limited type
can “become nonlimited” under certain circumstances, which
makes “limited” somewhat problematic as a class of types.
10.e/2
{
AI95-00442-01}
Normatively, the language-defined classes
are those that are defined to be inherited on derivation by 3.4;
other properties either aren't interesting or form categories, not classes.
11/2
{
AI95-00442-01}
These language-defined
categories classes
are organized like this:
12/2
{
AI95-00345-01}
all types
elementary
scalar
discrete
enumeration
character
boolean
other enumeration
integer
signed integer
modular integer
real
floating point
fixed point
ordinary fixed point
decimal fixed point
access
access-to-object
access-to-subprogram
composite
untagged
array
string
other array
untagged record
tagged
task
protected
tagged (including interfaces)
nonlimited tagged record
limited tagged
limited tagged record
synchronized tagged
tagged task
tagged protected
13/2
{
AI95-00345-01}
{
AI95-00442-01}
There are other categories, such as The
classes “numeric” and “
discriminated nonlimited”
,
which represent other
categorization classification
dimensions
, but and
do not fit into the above strictly hierarchical picture.
13.a.1/2
Discussion: {
AI95-00345-01}
{
AI95-00442-01}
Note that this is also true for some categories
mentioned in the chart. The category “task” includes both
untagged tasks and tagged tasks. Similarly for “protected”,
“limited”, and “nonlimited” (note that limited
and nonlimited are not shown for untagged composite types).
Wording Changes from Ada 83
13.a
This clause and its subclauses now precede the
clause and subclauses on objects and named numbers, to cut down on the
number of forward references.
13.b
We have dropped the term "base type"
in favor of simply "type" (all types in Ada 83 were "base
types" so it wasn't clear when it was appropriate/necessary to say
"base type"). Given a subtype S of a type T, we call T the
"type of the subtype S."
Wording Changes from Ada 95
13.c/2
{
AI95-00231-01}
Added a mention of null exclusions when we're talking
about constraints (these are not constraints, but they are similar).
13.d/2
{
AI95-00251-01}
Defined an interface type to be a composite type.
13.e/2
{
AI95-00326-01}
Revised the wording so that it is clear that an
incomplete view is similar to a partial view in terms of the language.
13.f/2
{
AI95-00366-01}
Added a definition of component of a type, subcomponent
of a type, and part of a type. These are commonly used in the standard,
but they were not previously defined.
13.g/2
{
AI95-00442-01}
Reworded most of this clause to use category rather
than class, since so many interesting properties are not, strictly speaking,
classes. Moreover, there was no normative description of exactly which
properties formed classes, and which did not. The real definition of
class, along with a list of properties, is now in 3.4.