# 12.7 Formal Packages

This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue

[ Formal packages can be used to pass packages to a generic unit. The `formal_package_declaration`

declares that the formal package is an instance of a given generic package. Upon instantiation, the actual package has to be an instance of that generic package.]

#### Syntax

2/3`formal_package_declaration`

` ::= `

**with** **package** `defining_identifier`

**is** **new** *generic_package_*`name`

`formal_package_actual_part`

[`aspect_specification`

];

3/2`formal_package_actual_part`

` ::= `

([**others** =>] <>)

| [`generic_actual_part`

]

| (`formal_package_association`

{, `formal_package_association`

} [, **others** => <>])

3.1/2`formal_package_association`

` ::= `

`generic_association`

| *generic_formal_parameter_*`selector_name`

=> <>

3.2/2Any positional `formal_package_association`

s shall precede any named `formal_package_association`

s.

#### Legality Rules

4The *generic_package_*`name`

shall denote a generic package (the *template* for the formal package); the formal package is an instance of the template.

The *generic_formal_parameter_*`selector_name`

of a `formal_package_association`

shall denote a `generic_formal_parameter_declaration`

of the template. If two or more formal subprograms of the template have the same defining name, then named associations are not allowed for the corresponding actuals.

A `formal_package_actual_part`

shall contain at most one `formal_package_association`

for each formal parameter. If the `formal_package_actual_part`

does not include “**others** => <>”, each formal parameter without an association shall have a `default_expression`

or `subprogram_default`

.

The rules for matching between `formal_package_association`

s and the generic formals of the template are as follows:

- If all of the
`formal_package_association`

s are given by generic associations, the`explicit_generic_actual_parameter`

s of the`formal_package_association`

s shall be legal for an instantiation of the template. 4.5/5 - If a
`formal_package_association`

for a formal type*T*of the template is given by <>, then the`formal_package_association`

for any other`generic_formal_parameter_declaration`

of the template that mentions*T*directly or indirectly shall also be given by <> .

`generic_formal_parameter_declaration`

*F*is replaced with a new entity

*F*' that has the same characteristics as

*F*: if

*F*is a formal discrete type then

*F*' is a discrete type, if

*F*is a formal subprogram then

*F*' is a subprogram with a similar signature, etc. In practice this is achieved by making the association into a copy of the declaration of the generic formal.

The actual shall be an instance of the template. If the `formal_package_actual_part`

is (<>) or (**others** => <>), [then the actual may be any instance of the template]; otherwise, certain of the actual parameters of the actual instance shall match the corresponding actual parameters of the formal package, determined as follows:

- If the
`formal_package_actual_part`

includes`generic_association`

s as well as associations with <>, then only the actual parameters specified explicitly with`generic_association`

s are required to match; 5.2/2 - Otherwise, all actual parameters shall match[, whether any actual parameter is given explicitly or by default].

The rules for matching of actual parameters between the actual instance and the formal package are as follows:

- For a formal object of mode
**in**, the actuals match if they are static expressions with the same value, or if they statically denote the same constant, or if they are both the literal**null**.

- For a formal subtype, the actuals match if they denote statically matching subtypes.
- For other kinds of formals, the actuals match if they statically denote the same entity.

{*8652/0039*} For the purposes of matching, any actual parameter that is the name of a formal object of mode **in** is replaced by the formal object's actual expression (recursively).

#### Static Semantics

9A `formal_package_declaration`

declares a generic formal package.

The visible part of a formal package includes the first list of `basic_declarative_item`

s of the `package_specification`

. In addition, for each actual parameter that is not required to match, a copy of the declaration of the corresponding formal parameter of the template is included in the visible part of the formal package. If the copied declaration is for a formal type, copies of the implicit declarations of the primitive subprograms of the formal type are also included in the visible part of the formal package.

`formal_package_actual_part`

is (<>), then the declarations that occur immediately within the `generic_formal_part`

of the template for the formal package are visible outside the formal package, and can be denoted by expanded names outside the formal package. If only some of the actual parameters are given by <>, then the declaration corresponding to those parameters (but not the others) are made visible. `generic_formal_part`

as well as the explicit declarations, so we get operations on the formal types. For the purposes of matching, if the actual instance *A* is itself a formal package, then the actual parameters of *A* are those specified explicitly or implicitly in the `formal_package_actual_part`

for *A*, plus, for those not specified, the copies of the formal parameters of the template included in the visible part of *A*.

#### Examples

12/2*Example of a generic package with formal package parameters:*

```
with Ada.Containers.Ordered_Maps; -- see A.18.6
generic
with package Mapping_1 is new Ada.Containers.Ordered_Maps(<>);
with package Mapping_2 is new Ada.Containers.Ordered_Maps
(Key_Type => Mapping_1.Element_Type,
others => <>);
package Ordered_Join is
-- Provide a "join" between two mappings
14/2subtype Key_Type is Mapping_1.Key_Type;
subtype Element_Type is Mapping_2.Element_Type;
15/2function Lookup(Key : Key_Type) return Element_Type;
16/2...
end Ordered_Join;
```

17/2*Example of an instantiation of a package with formal packages:*

```
with Ada.Containers.Ordered_Maps;
package Symbol_Package is
19/5subtype Key_String is String(1..5);
type String_Id is ...
20/2type Symbol_Info is ...
21/5package String_Table is new Ada.Containers.Ordered_Maps
(Key_Type => Key_String ,
Element_Type => String_Id);
22/2package Symbol_Table is new Ada.Containers.Ordered_Maps
(Key_Type => String_Id,
Element_Type => Symbol_Info);
23/2package String_Info is new Ordered_Join(Mapping_1 => String_Table,
Mapping_2 => Symbol_Table);
24/2Apple_Info : constant Symbol_Info := String_Info.Lookup("Apple");
25/2end Symbol_Package;
```

#### Extensions to Ada 83

#### Extensions to Ada 95

#### Wording Changes from Ada 95

*8652/0039*}

**Corrigendum:**Corrected the description of formal package matching to say that formal parameters are always replaced by their actual parameters (recursively). This matches the actual practice of compilers, as the ACATS has always required this behavior.

#### Incompatibilities With Ada 2005

#### Extensions to Ada 2005

`aspect_specification`

can be used in a `formal_package_declaration`

. This is described in 13.1.1.