[Home] [Prev] [Next] [Index]

12.5 Formal Types

12.5 Formal Types

1
[A generic formal subtype can be used to pass to a generic unit a subtype whose type is in a certain class of types.]

1.a
Reason: We considered having intermediate syntactic categories formal_integer_type_definition, formal_real_type_definition, and formal_fixed_point_definition, to be more uniform with the syntax rules for non-generic-formal types. However, that would make the rules for formal types slightly more complicated, and it would cause confusion, since formal_discrete_type_definition would not fit into the scheme very well.

Syntax

2
formal_type_declaration ::=
    type defining_identifier[discriminant_part] is formal_type_definition;

3
formal_type_definition ::=
      formal_private_type_definition
    | formal_derived_type_definition
    | formal_discrete_type_definition
    | formal_signed_integer_type_definition
    | formal_modular_type_definition
    | formal_floating_point_definition
    | formal_ordinary_fixed_point_definition
    | formal_decimal_fixed_point_definition
    | formal_array_type_definition
    | formal_access_type_definition

Legality Rules

4
For a generic formal subtype, the actual shall be a subtype_mark; it denotes the (generic) actual subtype.

4.a
Ramification: When we say simply "formal" or "actual" (for a generic formal that denotes a subtype) we're talking about the subtype, not the type, since a name that denotes a formal_type_declaration denotes a subtype, and the corresponding actual also denotes a subtype.

Static Semantics

5
A formal_type_declaration declares a (generic) formal type, and its first subtype, the (generic) formal subtype.

5.a
Ramification: A subtype (other than the first subtype) of a generic formal type is not a generic formal subtype.

6
The form of a formal_type_definition determines a class to which the formal type belongs. For a formal_private_type_definition the reserved words tagged and limited indicate the class (see 12.5.1). For a formal_derived_type_definition the class is the derivation class rooted at the ancestor type. For other formal types, the name of the syntactic category indicates the class; a formal_discrete_type_definition defines a discrete type, and so on.

6.a
Reason: This rule is clearer with the flat syntax rule for formal_type_definition given above. Adding formal_integer_type_definition and others would make this rule harder to state clearly.

Legality Rules

7
The actual type shall be in the class determined for the formal.

7.a
Ramification: For example, if the class determined for the formal is the class of all discrete types, then the actual has to be discrete.

7.b
Note that this rule does not require the actual to belong to every class to which the formal belongs. For example, formal private types are in the class of composite types, but the actual need not be composite. Furthermore, one can imagine an infinite number of classes that are just arbitrary sets of types that obey the closed-under-derivation rule, and are therefore technically classes (even though we don't give them names, since they are uninteresting). We don't want this rule to apply to those classes.

7.c
"Limited" is not a "interesting" class, but "nonlimited" is; it is legal to pass a nonlimited type to a limited formal type, but not the other way around. The reserved word limited really represents a class containing both limited and nonlimited types. "Private" is not a class; a generic formal private type accepts both private and nonprivate actual types.

7.d
It is legal to pass a class-wide subtype as the actual if it is in the right class, so long as the formal has unknown discriminants.

Static Semantics

8
[The formal type also belongs to each class that contains the determined class.] The primitive subprograms of the type are as for any type in the determined class.  For a formal type other than a formal derived type, these are the predefined operators of the type; they are implicitly declared immediately after the declaration of the formal type.  In an instance, the copy of such an implicit declaration declares a view of the predefined operator of the actual type, even if this operator has been overridden for the actual type. [The rules specific to formal derived types are given in 12.5.1.]

8.a
Ramification: All properties of the type are as for any type in the class. Some examples: The primitive operations available are as defined by the language for each class. The form of constraint applicable to a formal type in a subtype_indication depends on the class of the type as for a nonformal type. The formal type is tagged if and only if it is declared as a tagged private type, or as a type derived from a (visibly) tagged type. (Note that the actual type might be tagged even if the formal type is not.)

NOTES

9 7
Generic formal types, like all types, are not named. Instead, a name can denote a generic formal subtype. Within a generic unit, a generic formal type is considered as being distinct from all other (formal or nonformal) types.

9.a
Proof: This follows from the fact that each formal_type_declaration declares a type.

10 8
A discriminant_part is allowed only for certain kinds of types, and therefore only for certain kinds of generic formal types. See 3.7.

10.a
Ramification: The term "formal floating point type" refers to a type defined by a formal_floating_point_definition. It does not include a formal derived type whose ancestor is floating point. Similar terminology applies to the other kinds of formal_type_definition.

Examples

11
Examples of generic formal types:

12
type Item is private;
type Buffer(Length : Natural) is limited private;

13
type Enum  is (<>);
type Int   is range <>;
type Angle is delta <>;
type Mass  is digits <>;

14
type Table is array (Enum) of Item;

15
Example of a generic formal part declaring a formal integer type:

16
generic
   type Rank is range <>;
   First  : Rank := Rank'First;
   Second : Rank := First + 1;  --the operator "+" of the type Rank  

Wording Changes From Ada 83

16.a
RM83 has separate sections "Generic Formal Xs" and "Matching Rules for Formal Xs" (for various X's) with most of the text redundant between the two. We have combined the two in order to reduce the redundancy. In RM83, there is no "Matching Rules for Formal Types" section; nor is there a "Generic Formal Y Types" section (for Y = Private, Scalar, Array, and Access). This causes, for example, the duplication across all the "Matching Rules for Y Types" sections of the rule that the actual passed to a formal type shall be a subtype; the new organization avoids that problem.

16.b
The matching rules are stated more concisely.

16.c
We no longer consider the multiplying operators that deliver a result of type universal_fixed to be predefined for the various types; there is only one of each in package Standard.  Therefore, we need not mention them here as RM83 had to.

12.5.1 Formal Private and Derived Types

1
[The class determined for a formal private type can be either limited or nonlimited, and either tagged or untagged; no more specific class is known for such a type. The class determined for a formal derived type is the derivation class rooted at the ancestor type.]

Syntax

2
formal_private_type_definition ::= [[abstract] tagged] [limited] private

3
formal_derived_type_definition ::= [abstract] new subtype_mark [with private]

Legality Rules

4
If a generic formal type declaration has a known_discriminant_part, then it shall not include a default_expression for a discriminant.

4.a
Ramification: Consequently, a generic formal subtype with a known_discriminant_part is an indefinite subtype, so the declaration of a stand-alone variable has to provide a constraint on such a subtype, either explicitly, or by its initial value.

5
The ancestor subtype of a formal derived type is the subtype denoted by the subtype_mark of the formal_derived_type_definition. For a formal derived type declaration, the reserved words with private shall appear if and only if the ancestor type is a tagged type; in this case the formal derived type is a private extension of the ancestor type and the ancestor shall not be a class-wide type. [Similarly, the optional reserved word abstract shall appear only if the ancestor type is a tagged type].

5.a
Reason: We use the term "ancestor" here instead of "parent" because the actual can be any descendant of the ancestor, not necessarily a direct descendant.

6
If the formal subtype is definite, then the actual subtype shall also be definite.

6.a
Ramification: On the other hand, for an indefinite formal subtype, the actual can be either definite or indefinite.

7
For a generic formal derived type with no discriminant_part:

8 ·
If the ancestor subtype is constrained, the actual subtype shall be constrained, and shall be statically compatible with the ancestor;

8.a
Ramification: In other words, any constraint on the ancestor subtype is considered part of the "contract."

9 ·
If the ancestor subtype is an unconstrained access or composite subtype, the actual subtype shall be unconstrained.

9.a
Reason: This rule ensures that if a composite constraint is allowed on the formal, one is also allowed on the actual. If the ancestor subtype is an unconstrained scalar subtype, the actual is allowed to be constrained, since a scalar constraint does not cause further constraints to be illegal.

10 ·
If the ancestor subtype is an unconstrained discriminated subtype, then the actual shall have the same number of discriminants, and each discriminant of the actual shall correspond to a discriminant of the ancestor, in the sense of 3.7.

10.a
Reason: This ensures that if a discriminant constraint is given on the formal subtype, the corresponding constraint in the instance will make sense, without additional run-time checks. This is not necessary for arrays, since the bounds cannot be overridden in a type extension. An unknown_discriminant_part may be used to relax these matching requirements.

11
The declaration of a formal derived type shall not have a known_discriminant_part. For a generic formal private type with a known_discriminant_part:

12 ·
The actual type shall be a type with the same number of discriminants.

13 ·
The actual subtype shall be unconstrained.

14 ·
The subtype of each discriminant of the actual type shall statically match the subtype of the corresponding discriminant of the formal type.

14.a
Reason: We considered defining the first and third rule to be called "subtype conformance" for discriminant_parts. We rejected that idea, because it would require implicit (inherited) discriminant_parts, which seemed like too much mechanism.

15
[For a generic formal type with an unknown_discriminant_part, the actual may, but need not, have discriminants, and may be definite or indefinite.]

Static Semantics

16
The class determined for a formal private type is as follows:

17
Type Definition                               Determined Class

limited private the class of all types
private the class of all nonlimited types
tagged limited private the class of all tagged types
tagged private the class of all nonlimited tagged types

18
[The presence of the reserved word abstract determines whether the actual type may be abstract.]

19
A formal private or derived type is a private or derived type, respectively. A formal derived tagged type is a private extension. [A formal private or derived type is abstract if the reserved word abstract appears in its declaration.]

20
If the ancestor type is a composite type that is not an array type, the formal type inherits components from the ancestor type (including discriminants if a new discriminant_part is not specified), as for a derived type defined by a derived_type_definition (see 3.4).

21
For a formal derived type, the predefined operators and inherited user-defined subprograms are determined by the ancestor type, and are implicitly declared at the earliest place, if any, within the immediate scope of the formal type, where the corresponding primitive subprogram of the ancestor is visible (see 7.3.1). In an instance, the copy of such an implicit declaration declares a view of the corresponding primitive subprogram of the ancestor, even if this primitive has been overridden for the actual type. [In the case of a formal private extension, however, the tag of the formal type is that of the actual type, so if the tag in a call is statically determined to be that of the formal type, the body executed will be that corresponding to the actual type.]

21.a
Ramification: The above rule defining the properties of primitive subprograms in an instance applies even if the subprogram has been overridden or hidden for the actual type. This rule is necessary for untagged types, because their primitive subprograms might have been overridden by operations that are not subtype-conformant with the operations defined for the class. For tagged types, the rule still applies, but the primitive subprograms will dispatch to the appropriate implementation based on the type and tag of the operands. Even for tagged types, the formal parameter names and default_expressions are determined by those of the primitive subprograms of the specified ancestor type.

22
For a prefix S that denotes a formal indefinite subtype, the following attribute is defined:

23
S'Definite S'Definite yields True if the actual subtype corresponding to S is definite; otherwise it yields False.  The value of this attribute is of the predefined type Boolean.

23.a
Discussion:  Whether an actual subtype is definite or indefinite may have a major effect on the algorithm used in a generic. For example, in a generic I/O package, whether to use fixed-length or variable-length records could depend on whether the actual is definite or indefinite. This attribute is essentially a replacement for the Constrained attribute which is now considered obsolete.

NOTES

24 9
In accordance with the general rule that the actual type shall belong to the class determined for the formal (see 12.5, "Formal Types"):

25 ·
If the formal type is nonlimited, then so shall be the actual;

26 ·
For a formal derived type, the actual shall be in the class rooted at the ancestor subtype.

27 10
[The actual type can be abstract only if the formal type is abstract (see 3.9.3).]

27.a
Reason: This is necessary to avoid contract model problems, since one or more of its primitive subprograms are abstract; it is forbidden to create objects of the type, or to declare functions returning the type.

27.b
Ramification: On the other hand, it is OK to pass a non-abstract actual to an abstract formal - abstract on the formal indicates that the actual might be abstract.

28 11
If the formal has a discriminant_part, the actual can be either definite or indefinite. Otherwise, the actual has to be definite.

Incompatibilities With Ada 83

28.a
Ada 83 does not have unknown_discriminant_parts, so it allows indefinite subtypes to be passed to definite formals, and applies a legality rule to the instance body. This is a contract model violation. Ada 9X disallows such cases at the point of the instantiation. The workaround is to add (<>) as the discriminant_part of any formal subtype if it is intended to be used with indefinite actuals. If that's the intent, then there can't be anything in the generic body that would require a definite subtype.

28.b
The check for discriminant subtype matching is changed from a run-time check to a compile-time check.

12.5.2 Formal Scalar Types

1
A formal scalar type is one defined by any of the formal_type_definitions in this subclause. [The class determined for a formal scalar type is discrete, signed integer, modular, floating point, ordinary fixed point, or decimal.]

Syntax

2
formal_discrete_type_definition ::= (<>)

3
formal_signed_integer_type_definition ::= range <>

4
formal_modular_type_definition ::= mod <>

5
formal_floating_point_definition ::= digits <>

6
formal_ordinary_fixed_point_definition ::= delta <>

7
formal_decimal_fixed_point_definition ::= delta <> digits <>

Legality Rules

8
The actual type for a formal scalar type shall not be a nonstandard numeric type.

8.a
Reason: This restriction is necessary because nonstandard numeric types have some number of restrictions on their use, which could cause contract model problems in a generic body.  Note that nonstandard numeric types can be passed to formal derived and formal private subtypes, assuming they obey all the other rules, and assuming the implementation allows it (being nonstandard means the implementation might disallow anything).

NOTES

9 12
The actual type shall be in the class of types implied by the syntactic category of the formal type definition (see 12.5, "Formal Types").  For example, the actual for a formal_modular_type_definition shall be a modular type.

12.5.3 Formal Array Types

1
[The class determined for a formal array type is the class of all array types.]

Syntax

2
formal_array_type_definition ::= array_type_definition

Legality Rules

3
The only form of discrete_subtype_definition that is allowed within the declaration of a generic formal (constrained) array subtype is a subtype_mark.

3.a
Reason: The reason is the same as for forbidding constraints in subtype_indications (see 12.1).

4
For a formal array subtype, the actual subtype shall satisfy the following conditions:

5 ·
The formal array type and the actual array type shall have the same dimensionality; the formal subtype and the actual subtype shall be either both constrained or both unconstrained.

6 ·
For each index position, the index types shall be the same, and the index subtypes (if unconstrained), or the index ranges (if constrained), shall statically match (see 4.9.1).

7 ·
The component subtypes of the formal and actual array types shall statically match.

8 ·
If the formal type has aliased components, then so shall the actual.

8.a
Ramification: On the other hand, if the formal's components are not aliased, then the actual's components can be either aliased or not.

Examples

9
Example of formal array types:

10
--given the generic package

11
generic
   type Item   is private;
   type Index  is (<>);
   type Vector is array (Index range <>) of Item;
   type Table  is array (Index) of Item;
package P is
   ...
end P;

12
--and the types

13
type Mix    is array (Color range <>) of Boolean;
type Option is array (Color) of Boolean;

14
--then Mix can match Vector and Option can match Table

15
package R is new P(Item   => Boolean, Index => Color,
                   Vector => Mix,     Table => Option);

16
--Note that Mix cannot match Table and Option cannot match Vector

Incompatibilities With Ada 83

16.a
The check for matching of component subtypes and index subtypes or index ranges is changed from a run-time check to a compile-time check. The Ada 83 rule that "If the component type is not a scalar type, then the component subtypes shall be either both constrained or both unconstrained" is removed, since it is subsumed by static matching. Likewise, the rules requiring that component types be the same is subsumed.

12.5.4 Formal Access Types

1
[The class determined for a formal access type is the class of all access types.]

Syntax

2
formal_access_type_definition ::= access_type_definition

Legality Rules

3
For a formal access-to-object type, the designated subtypes of the formal and actual types shall statically match.

4
If and only if the general_access_modifier constant applies to the formal, the actual shall be an access-to-constant type. If the general_access_modifier all applies to the formal, then the actual shall be a general access-to-variable type (see 3.10).

4.a
Ramification: If no _modifier applies to the formal, then the actual type may be either a pool-specific or a general access-to-variable type.

5
For a formal access-to-subprogram subtype, the designated profiles of the formal and the actual shall be mode-conformant, and the calling convention of the actual shall be protected if and only if that of the formal is protected.

5.a
Reason: We considered requiring subtype conformance here, but mode conformance is more flexible, given that there is no way in general to specify the convention of the formal.

Examples

6
Example of formal access types:

7
--the formal types of the generic package

8
generic
   type Node is private;
   type Link is access Node;
package P is
   ...
end P;

9
--can be matched by the actual types

10
type Car;
type Car_Name is access Car;

11
type Car is
   record
      Pred, Succ : Car_Name;
      Number     : License_Number;
      Owner      : Person;
   end record;

12
--in the following generic instantiation

13
package R is new P(Node => Car, Link => Car_Name);

Incompatibilities With Ada 83

13.a
The check for matching of designated subtypes is changed from a run-time check to a compile-time check. The Ada 83 rule that "If the designated type is other than a scalar type, then the designated subtypes shall be either both constrained or both unconstrained" is removed, since it is subsumed by static matching.

Extensions to Ada 83

13.b
Formal access-to-subprogram subtypes and formal general access types are new concepts.



[Home] [Prev] [Next] [Index]

documentation@rational.com
Copyright © 1993-1998, Rational Software Corporation.   All rights reserved.