Version 1.2 of ai12s/ai12-0297-1.txt

Unformatted version of ai12s/ai12-0297-1.txt version 1.2
Other versions for file ai12s/ai12-0297-1.txt

!standard 12.4 (6)          18-12-06 AI12-0297-1/01
!standard 12.7 (2)
!class amendment 18-12-06
!status Hold 9-0-1 19-02-26
!status work item 18-12-06
!status received 18-12-06
!priority Medium
!difficulty Medium
!subject Defaults for generic formal packages and formal "in out" objects
!summary
The syntax of generic formal package, and formal "in out" object parameters are modified to permit defaults.
!problem
Ada 2012 does not have defaults for generic formal types, packages, or objects of mode "in out". While not a serious problem (users can always be forced to supply explicit values for all parameters), it is sometimes a nuisance and unnecessarily complicates some generic instantiations. Allowing more kinds of defaults for generic formal parameters can significantly ease the use of generic units. Defaults for formal types are covered in AI12-0205-1. This AI addresses defaults for formal packages and formal "in out" objects.
!proposal
Defaults for generic formal packages ------------------------------------
12.7 (2) is modified to read
formal_package_declaration ::= with package defining_identifier is new generic_package_name formal_actual_part [or use default_package_name];
The optional "or use package_name" defines a default package to be used if an instantiation does not explicitly provide an actual for that parameter. 12.3(7 and 10) are modified to include default_package_name as an option for missing parameter associations. (Note: "default_package_" is in italics in default_package_name.) The package denoted by default_package_name must be an instantiation of the generic package denoted by generic_package_name and the formal_actual_part must be (<>) or (others => <>).
Defaults for generic formal "in out" objects --------------------------------------------
12.3 (2) is modified to read:
formal_object_declaration ::= defining_identifier_list : mode [null_exclusion] subtype_mark [object_default] [aspect_specification]; | defining_identifier_list : mode access_definition [object_default] [aspect_specification];
object_default ::= := default_expression | or use default_name
The optional object_default of form "or use default_name" defines a default object to be used if an instantiation does not explicitly provide an actual for that parameter. 12.3(7 and 10) are modified to say object_default instead of default_expression. Paragraph 12.4(6) is modified to allow a formal object of mode "in out" to have an object_default of the form "or use default_name". In the case where an object_default is of the form "or use default_name", the default_name must denote a variable of the type of the subtype specified in the formal_object_declaration.
!discussion
The basic idea behind these changes is to allow more forms of generic parameters to have defaults. Currently, only subprograms and "in" objects may have a default value. However, the benefits of default parameters can exist for any kind of parameter. Note that defaults for generic formal types are proposed in AI12-0205-1. This AI adds defaults for formal packages and formal objects of mode "in out".
The aim of these changes is to make generic instantiations simpler to write, or rather, to give designers of generic units the means to design their units such that instantiations can be made simpler than today. It is often possible to supply reasonable default values for some of the entities to which the above proposal applies.
The syntax for new forms of default is hard to define. 'Or use' was selected because the default is alternative to specifying an actual. We don't want to use "is" as is done for formal subprograms, because "is" is already a part of formal package (and type) declarations. We also considered using a new keyword ('default'), the assignment symbol (':='), and various other combinations of existing reserved words ("use", "until others", "else"). "Use" alone is unacceptable because adding a semicolon would make another syntactically legal program (and semantically legal program for packages). All of the others might be OK, but (except for "else") don't have the right flavor. For example, in the case of formal objects of mode "in out", ":=" would seem to imply copying the actual object, whereas such formals behave like renamings, and ":=" also wouldn't make sense for types.
[Editor's note: I used Bob Duff's suggestion of "or use" in this AI. I thought it read better than the other suggestions. It has the advantage of not being any of the syntax choices considered in the rejected 2002 edition of this AI, and we've already used "and" in the syntax for a purpose other than logical operations. "Or" is probably feeling left out. :-)]
Defaults for formal_packages are only allowed in the case where the formal_actual_part is given by a "<>" (and no other parameters are specified), because it doesn't seem common or likely that there would be a default that would match the specified actuals. Also, AI12-0268-1 proposes another mechanism to determine a default in such cases (a form of implicit instances).
Defaults would have proven useful in the development of a library of container abstractions. A short discussion on comp.lang.ada revealed that several developers of container libraries have come across these issues and perceive them as shortcomings of Ada 95.
!example
An example for defaults for generic formal packages ---------------------------------------------------
Consider a hash table container abstraction using a signature package for the key type:
generic type Key_Type (<>) is private; with function Hash (Key : in Key_Type) return Natural; with function "=" (L, R : in Key_Type) return Boolean is <>; package Hashable is -- Signature package. end Hashable;
generic with package Keys is new Hashable (<>); type Item_Type (<>) is private; Initial_Default_Size : Positive := 23; package Hash_Tables is
type Hash_Table is private;
procedure Insert (Table : in out Hash_Table; Key : in Keys.Key_Type; Item : in Item_Type);
-- ... Other operations on hash tables
end Hash_Tables;
Then, one could get a package for hash tables with strings as keys as follows:
with Hash_Support; package String_Keys is new Hashable (Key_Type => String, Hash => Hash_Support.Hash_String);
generic with package Keys is new Hashable (<>) or use String_Keys; -- New syntax. type Item_Type (<>) is private; Initial_Default_Size : Positive := 23; package String_Hash_Tables is package Table is Hash_Tables (Keys, Item_Type, Initial_Default_Size); -- Probably would use renames here to make the contents directly visible. end String_Hash_Tables;
with the same instantiations for finally getting concrete hash tables:
package My_Hash_Tables is new String_Hash_Tables (Item_Type => My_Data);
package My_Other_Hash_Tables is new String_Hash_Tables (Item_Type => My_Other_Data);
An example for defaults for generic formal "in out" objects -----------------------------------------------------------
The motivating example for default values for generic formal "in out" objects is the storage pool parameter often found in container libraries:
generic type Item_Type is private; with function "=" (L, R : in Item_Type) return Boolean is <>; Pool : in out System.Storage.Root_Storage_Pool'Class; package Lists is
type List is private;
-- Operations on lists...
private
type Node; type Link is access all Node; for Link'Storage_Pool use Pool;
type Node is record Data : Item_Type; Next, Prev : Link; end record;
type List is new Ada.Finalization.Controlled with record Head, Tail : Link; end record;
end Lists;
Many users just don't care about storage pools (or even don't know what they are be good for). Advanced users, however, may well want to specify the pool in which the list should allocate its nodes, hence adding the pool as a generic formal parameter clearly makes sense. Unfortunately, it confuses less advanced users (and generally complicates instantiation in those cases where one really doesn't care).
If one could provide a default value for "Pool", this confusion or complication could be avoided: we could simply declare the package as
generic type Item_Type is private; with function "=" (L, R : in Item_Type) return Boolean is <>; Pool : in out System.Storage.Root_Storage_Pool'Class := The_Default_Pool; -- New syntax package Lists is ...
[For this example, we won't define what "The_Default_Pool" actually might be. For many implementations, a possible declaration might be a pre-written pool that just uses the standard pool of some arbitrary access type.]
With defaults for generic formal "in out" objects, an instantiation of this list package can be as simple as
package My_Lists is new Lists (My_Type);
Inexperienced users or users who choose not to care about storage pools can use the package without extra hassles, while experienced or concerned users still have the possibility to provide their own storage pool.
!ASIS
** Unknown ASIS effect **
!ACATS test
New ACATS B-Tests and C-Tests will be needed to test this feature.
!appendix

From: Gary Dismukes
Sent: Thursday, December 6, 2018  5:01 PM

Here's the last part of my homework, a new AI split off from AI-0205-1.
[This is version /01 of this AI - Editor.]

****************************************************************

Questions? Ask the ACAA Technical Agent