Ada Reference Manual (Ada 2022) — Legal Information

# 12.6 Formal Subprograms

1
Formal subprograms can be used to pass callable entities to a generic unit.

#### Syntax

2/2
formal_subprogram_declaration ::= formal_concrete_subprogram_declaration
| formal_abstract_subprogram_declaration
2.1/3
formal_concrete_subprogram_declaration ::=
with subprogram_specification [is subprogram_default]
[aspect_specification];
2.2/3
formal_abstract_subprogram_declaration ::=
with subprogram_specification is abstract [subprogram_default]
[aspect_specification];
3/2
subprogram_default ::= default_name | <> | null
4
default_name ::= name
4.1/2
A subprogram_default of null shall not be specified for a formal function or for a formal_abstract_subprogram_declaration.

#### Name Resolution Rules

5
The expected profile for the default_name, if any, is that of the formal subprogram.
6
For a generic formal subprogram, the expected profile for the actual is that of the formal subprogram.

#### Legality Rules

7/3
The profiles of the formal and any named default shall be mode conformant.
8/3
The profiles of the formal and actual shall be mode conformant.
8.1/2
For a parameter or result subtype of a formal_subprogram_declaration that has an explicit null_exclusion:
8.2/5
if the actual matching the formal_subprogram_declaration statically denotes a generic formal subprogram of another generic unit G, and the instantiation containing the actual occurs within the body of a generic unit G or within the body of a generic unit declared within the declarative region of the generic unit G, then the corresponding parameter or result type of the formal subprogram of G shall have a null_exclusion;
8.3/2
otherwise, the subtype of the corresponding parameter or result type of the actual matching the formal_subprogram_declaration shall exclude null. In addition to the places where Legality Rules normally apply (see 12.3), this rule applies also in the private part of an instance of a generic unit.
8.4/5
If the named default, if any, is a prefixed view, the prefix of that view shall denote an object for which renaming is allowed (see 8.5.1). Similarly, if the actual subprogram in an instantiation is a prefixed view, the prefix of that view shall denote an object for which renaming is allowed.
8.5/5
If a formal parameter of a formal_abstract_subprogram_declaration is of a specific tagged type T or of an anonymous access type designating a specific tagged type T, T is called a controlling type of the formal_abstract_subprogram_declaration. Similarly, if the result of a formal_abstract_subprogram_declaration for a function is of a specific tagged type T or of an anonymous access type designating a specific tagged type T, T is called a controlling type of the formal_abstract_subprogram_declaration. A formal_abstract_subprogram_declaration shall have exactly one controlling type, and that type shall not be incomplete.
8.6/5
The actual subprogram for a formal_abstract_subprogram_declaration shall be:
8.7/5
a dispatching operation of the controlling type; or
8.8/5
if the controlling type is a formal type, and the actual type corresponding to that formal type is a specific type T, a dispatching operation of type T; or
8.9/5
if the controlling type is a formal type, and the actual type is a class-wide type T'Class, an implicitly declared subprogram corresponding to a primitive operation of type T (see Static Semantics below).

#### Static Semantics

9
A formal_subprogram_declaration declares a generic formal subprogram. The types of the formal parameters and result, if any, of the formal subprogram are those determined by the subtype_marks given in the formal_subprogram_declaration; however, independent of the particular subtypes that are denoted by the subtype_marks, the nominal subtypes of the formal parameters and result, if any, are defined to be nonstatic, and unconstrained if of an array type (no applicable index constraint is provided in a call on a formal subprogram). In an instance, a formal_subprogram_declaration declares a view of the actual. The profile of this view takes its subtypes and calling convention from the original profile of the actual entity, while taking the formal parameter names and default_expressions from the profile given in the formal_subprogram_declaration. The view is a function or procedure, never an entry.
9.1/3
If a subtype_mark in the profile of the formal_subprogram_declaration denotes a formal private or formal derived type and the actual type for this formal type is a class-wide type T'Class, then for the purposes of resolving the corresponding actual subprogram at the point of the instantiation, certain implicit declarations may be available as possible resolutions as follows:
9.2/3
For each primitive subprogram of T that is directly visible at the point of the instantiation, and that has at least one controlling formal parameter, a corresponding implicitly declared subprogram with the same defining name, and having the same profile as the primitive subprogram except that T is systematically replaced by T'Class in the types of its profile, is potentially use-visible. The body of such a subprogram is as defined in 12.5.1 for primitive subprograms of a formal type when the actual type is class-wide.
10
If a generic unit has a subprogram_default specified by a box, and the corresponding actual parameter is omitted, then it is equivalent to an explicit actual parameter that is a usage name identical to the defining name of the formal.
10.1/2
If a generic unit has a subprogram_default specified by the reserved word null, and the corresponding actual parameter is omitted, then it is equivalent to an explicit actual parameter that is a null procedure having the profile given in the formal_subprogram_declaration.
10.2/2
The subprogram declared by a formal_abstract_subprogram_declaration with a controlling type T is a dispatching operation of type T.
11/5
NOTE 1 The matching rules for formal subprograms state requirements that are similar to those applying to subprogram_renaming_declarations (see 8.5.4). In particular, the name of a parameter of the formal subprogram can be different from that of the corresponding parameter of the actual subprogram; similarly, for these parameters, default_expressions can be different.
12
NOTE 2 The constraints that apply to a parameter of a formal subprogram are those of the corresponding formal parameter of the matching actual subprogram (not those implied by the corresponding subtype_mark in the _specification of the formal subprogram). A similar remark applies to the result of a function. Therefore, to avoid confusion, it is recommended that the name of a first subtype be used in any declaration of a formal subprogram.
13
NOTE 3 The subtype specified for a formal parameter of a generic formal subprogram can be any visible subtype, including a generic formal subtype of the same generic_formal_part.
14
NOTE 4 A formal subprogram is matched by an attribute of a type if the attribute is a function with a matching specification. An enumeration literal of a given type matches a parameterless formal function whose result type is the given type.
15/5
NOTE 5 A default_name denotes an entity that is visible or directly visible at the place of the generic_declaration; a box used as a default is equivalent to a name that denotes an entity that is directly visible at the place of the generic_instantiation.
16/2
NOTE 6 The actual subprogram cannot be abstract unless the formal subprogram is a formal_abstract_subprogram_declaration (see 3.9.3).
16.1/5
NOTE 7 The subprogram declared by a formal_abstract_subprogram_declaration is an abstract subprogram. All calls on a subprogram declared by a formal_abstract_subprogram_declaration are limited to dispatching calls. See 3.9.3.
16.2/2
NOTE 8 A null procedure as a subprogram default has convention Intrinsic (see 6.3.1).

#### Examples

17
Examples of generic formal subprograms:
18/2
with function "+"(X, Y : Item) return Item is <>;
with function Image(X : Enum) return String is Enum'Image;
with procedure Update is Default_Update;
with procedure Pre_Action(X : in Item) is null; -- defaults to no action
with procedure Write(S : not null access Root_Stream_Type'Class;
Desc : Descriptor)
is abstract Descriptor'Write; -- see 13.13.2
-- Dispatching operation on Descriptor with default
19
-- given the generic procedure declaration
20
generic
with procedure Action (X : in Item);
procedure Iterate(Seq : in Item_Sequence);
21
-- and the procedure
22
procedure Put_Item(X : in Item);
23
-- the following instantiation is possible
24
procedure Put_List is new Iterate(Action => Put_Item);

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