12.7 Formal Packages
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
Legality Rules
The 
generic_package_name 
shall denote a generic package (the 
template for the formal package); 
the formal package is an instance of the template.
 
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:
 
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. 
  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
 The visible part of a formal 
package includes the first list of 
basic_declarative_items 
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.
 
 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
 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 
   subtype Key_Type is Mapping_1.Key_Type;
   subtype Element_Type is Mapping_2.Element_Type;
   function Lookup(Key : Key_Type) return Element_Type;
   ...
end Ordered_Join;
 Example of an instantiation 
of a package with formal packages:
with Ada.Containers.Ordered_Maps;
package Symbol_Package is
   type String_Id is ...
   type Symbol_Info is ...
   package String_Table is new Ada.Containers.Ordered_Maps
           (Key_Type => String,
            Element_Type => String_Id);
   package Symbol_Table is new Ada.Containers.Ordered_Maps
           (Key_Type => String_Id,
            Element_Type => Symbol_Info);
   package String_Info is new Ordered_Join(Mapping_1 => String_Table,
                                           Mapping_2 => Symbol_Table);
   Apple_Info : constant Symbol_Info := String_Info.Lookup("Apple");
end Symbol_Package;
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe