Ada Conformity Assessment Authority |
Home |
Conformity Assessment | Test Suite |
ARG | Ada Standard |

A *type*
is characterized by a set of values, and a set of *primitive operations*
which implement the fundamental aspects of its semantics. An
*object* of a given type is a run-time entity that contains (has)
a value of the type.

{*AI95-00442-01*}
Types are grouped into *categories*
of types. There exist several *language-defined
categories* of types (see NOTES below), reflecting the similarity
of their values and primitive operations. [Most categories
of types form *classes* of types.] *Elementary*
types are those whose values are logically indivisible; *composite*
types are those whose values are composed of *component* values.

The elementary types are the
*scalar* types (*discrete* and *real*) and the *access*
types (whose values provide access to objects or subprograms). Discrete
types are either *integer* types or are defined by enumeration of
their values (*enumeration* types). Real types
are either *floating point* types or *fixed point* types.

{*AI95-00251-01*}
{*AI95-00326-01*}
The composite types are the *record* types, *record extensions*,
*array* types, *interface* types, *task* types, and *protected*
types.

{*AI95-00326-01*}
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].

{*AI95-00326-01*}
Certain composite types (and 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.

{*AI95-00366-01*}
The term *subcomponent* is used in this Reference
Manual 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. 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.

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.

{*AI95-00231-01*}
The set of possible values for an object of a given
type can be subjected to a condition that is called a *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).

{*AI95-00231-01*}
{*AI95-00415-01*}
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*. Similarly, the associated
constraint is called the *constraint of the subtype*.
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. Such values *belong* to the 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).

For scalar types, “constrained”
means “has a nonnull 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.

Class-wide subtypes are always unconstrained.

NOTES

2 {*AI95-00442-01*}
Any set of types can be called a “category” of types, and
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). 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*:
abstract, incomplete, interface, limited, private,
record.

{*AI95-00345-01*}
{*AI95-00442-01*}
Every property of types forms a category, but 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.

{*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”.

{*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.

{*AI95-00442-01*}
These language-defined categories are organized like this:

{*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

record

task

protected

tagged (including interfaces)

nonlimited tagged record

limited tagged

limited tagged record

synchronized tagged

tagged task

tagged protected

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

record

task

protected

tagged (including interfaces)

nonlimited tagged record

limited tagged

limited tagged record

synchronized tagged

tagged task

tagged protected

{*AI95-00345-01*}
{*AI95-00442-01*}
There are other categories, such as “numeric” and “discriminated”,
which represent other categorization dimensions, but do not fit into
the above strictly hierarchical picture.

{*AI05-0299-1*}
This subclause now precedes the subclauses on objects and named numbers,
to cut down on the number of forward references.

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."

{*AI95-00231-01*}
Added a mention of null exclusions when we're talking about constraints
(these are not constraints, but they are similar).

{*AI95-00251-01*}
Defined an interface type to be a composite type.

{*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.

{*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.

{*AI95-00442-01*}
{*AI05-0299-1*}
Reworded most of this subclause 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.

Ada 2005 and 2012 Editions sponsored in part by **Ada-Europe**