CVS difference for ais/ai-00299.txt

Differences between 1.1 and version 1.2
Log of other versions for file ais/ai-00299.txt

--- ais/ai-00299.txt	2002/06/14 23:48:56	1.1
+++ ais/ai-00299.txt	2002/10/01 03:08:54	1.2
@@ -1,4 +1,4 @@
-!standard 8.5.5 (2)                                    02-06-12  AI95-00299/01
+!standard 8.5.5 (2)                                    02-09-25  AI95-00299/02
 !standard 12.4 (6)
 !standard 12.5 (2)
 !standard 12.7 (2)
@@ -11,116 +11,88 @@
 
 !summary
 
-It is proposed to modify the syntax of generic formal type, package, and
-"in out" object parameters to permit default expressions. It is also
-proposed to modify the syntax of generic renaming declarations to permit
-supplying defaults.
+The syntax of generic formal type, package, and "in out" object parameters are
+modified to permit default expressions.
 
 !problem
 
-Ada 95 does not have defaults for generic formal types or packages,
-nor can generic renamings supply defaults for (some of) the formal
-parameters of the renamed generic unit. 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.
+Ada 95 does not have defaults for generic formal types or packages. 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.
 
 !proposal
 
-1. Defaults for generic formal types.
--------------------------------------
+Defaults for generic formal types
+---------------------------------
 
 12.5(2) is modified to read
 
   formal_type_declaration ::=
     type defining_identifier [discriminant_part] is
-      formal_type_definition [use subtype_mark];
+      formal_type_definition [else use default_subtype_mark];
 
-The idea is that the optional "use subtype_mark" defines a default type
-to be taken if an instantiation does not explicitly provide an actual
-for that parameter. The type denoted by "subtype_mark" must fulfill all
-the constraints/rules as if it occurred as a generic actual in a generic
-parameter association.
+The optional "else use subtype_mark" defines a default type
+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_subtype_mark
+as an option for missing parameter associations. (Note: "default_" is in
+italics in default_subtype_mark.) The subtype denoted by default_subtype_mark
+must fulfill all the constraints/rules as if it occurred as a
+generic actual in a generic parameter association.
 
-Note: one might also consider using ":=" instead of "use", but that's
-a purely syntactic issue.
 
+Defaults for generic formal packages
+------------------------------------
 
-2. 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 [:= package_name];
+      new generic_package_name formal_actual_part [else use default_package_name];
 
-with the intention that the ":= package_name" defines a default package
-to be taken if an instantiation does not explicitly provide an actual
-for that parameter. The package denoted by "package_name" must be an
-instantiation of the generic package denoted by "generic_package_name"
+The optional "else 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
 such that it fulfils the constraints imposed by the formal_actual_part.
 
-
-3. Defaults in generic renamings
---------------------------------
-
-8.5.5(2) is modified to read
-
-  generic_renaming_declaration ::=
-    generic package   defining_program_unit_name
-      renames generic_package_name   [generic_actual_part];
-   |generic procedure defining_program_unit_name
-      renames generic_procedure_name [generic_actual_part];
-   |generic function  defining_program_unit_name
-      renames generic_function_name  [generic_actual_part];
-
-The generic_actual_part may be incomplete in the sense that it is allowed
-to define actuals only for a subset of the generic formal parameters
-of the unit denoted by the generic_unit_name following the "renames".
-
-Those actuals given are taken as defaults for the corresponding generic
-formals for the renaming. In other word, a generic renaming may supply
-additional default values for generic formals that in the renamed unit
-did not have defaults, and it may change defaults of formals for which
-the declaration of the renamed unit already defined defaults.
 
-The actuals provided in a generic renaming declaration are just defaults;
-an instantiation of the unit declared by the generic renaming declaration
-may override those defaults by explicitly providing values for these
-formal parameters.
-
-
-4. Defaults for generic formal "in out" objects
------------------------------------------------
-
-It is proposed to delete paragraph 12.4(6).
+Defaults for generic formal "in out" objects
+--------------------------------------------
 
-As a result, generic formal "in out" objects may have defaults, too.
+It is proposed to delete paragraph 12.4(6). This will allow generic formal
+"in out" objects to have default expressions.
 
 
 !discussion
 
+The basic idea behind these changes is to allow all types 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.
+
 All of these changes aim at making 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.
 
-I cannot judge up-front how difficult or complex this would be to
-implement, but it appears to me to be relatively straight-forward: one
-just has to maintain info on what the defaults are, and in an instantiation,
-supply these defaults as the actuals for any generic formals that do not
-have explicit actuals. The whole instantiation process then should remain
-unchanged.
-
-All of these four change items have come up in the development of a library
-of container abstractions. A short discussion on comp.lang.ada revealed that
-apparently I'm not alone with these ideas; several developers of container
-libraries have come across these issues and perceive them as shortcomings
-of Ada 95.
+The syntax for default types is hard to define. 'Else use' was selected because
+a default type is an alternative to specifying an actual type. We also
+considered using a new keyword ('default'), the assignment symbol (':='), and various
+other combinations of existing reserved words ("use", "until others", "else").
+"Use" is unacceptable because adding a semicolon would make another
+syntactically legal program. All of the others would be OK, but (except for
+"else") don't have the right flavor. For instance, ":=" seems to imply
+copying a type (which can't happen).
+
+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
@@ -167,9 +139,9 @@
 
 end Lists;
 
-All operations would maintain L.N, e.g. Append would add 1. When this came
-up on comp.lang.ada, some people argued that if one has lists of oranges and
-lists of apples, these should be counted using different types to avoid
+All operations would maintain L.N, e.g. Append would add 1. When this was
+discussed on comp.lang.ada, some people argued that if one has lists of oranges
+and lists of apples, these should be counted using different types to avoid
 inadvertantly adding apple counts and orange counts. Hence the interface
 should be modified:
 
@@ -203,7 +175,7 @@
 
 generic
    type Item_Type is private;
-   type Item_Count is range <> use Natural; --  New syntax now!
+   type Item_Count is range <> else use Natural; --  New syntax.
    with function "=" (L, R : in Item_Type) return Boolean;
 package Lists is
 
@@ -211,88 +183,11 @@
 
 end Lists;
 
-The examples below also use defaults for generic formal types.
-
-
-An example for defaults in generic renamings
---------------------------------------------
-
-Consider a hash table container abstraction:
-
-generic
-   type Key_Type (<>) is private;
-   type Item_Type (<>) is private;
-   with function Hash (Key : in Key_Type) return Natural;
-   with function "=" (L, R : in Key_Type) return Boolean is <>;
-   Initial_Default_Size : Positive := 23;
-   --  Initial size of hash tables
-package Hash_Tables is
-
-   type Hash_Table is private;
-
-     procedure Insert
-       (Table : in out Hash_Table;
-        Key   : in     Key_Type;
-        Item  : in     Item_Type);
-
-   --  ... Other operations on hash tables
-
-end Hash_Tables;
 
-Now suppose for some reason, someone wants a version of this generic package
-in which all hash tables initially get some larger size. Easy to do with a
-generic renaming, supplying a new default for Initial_Default_Size:
-
-generic package Large_Hash_Tables
-  renames Hash_Tables (Initial_Default_Size => 101);
-
-And an instantiation like
-
-  package My_Small_Hash_Tables is
-    new Hash_Tables (String, My_Data, My_Hash_Function, "=");
-
-will offer hash tables that initially have a small size (23), whereas an
-instantiation like
-
-  package My_Large_Hash_Tables is
-    new Large_Hash_Tables (String, My_Data, My_Hash_Function, "=");
-
-will offer hash tables that initially have a larger size (101).
-
-Granted, the second instantiation could also have been written as
-
-  package My_Large_Hash_Tables is
-    new Hash_Tables (String, My_Data, My_Hash_Function, "=", 101);
-
-so maybe the example is not exactly the best, but it still nicely illustrates
-how providing defaults in a renaming may simplify things. Maybe a better
-example is to use a renaming to capture the most common case, namely the
-one where the key type is String (this example uses the proposed defaults for
-generic formal types):
-
-  package Hash_Support is
-
-     function Hash_String (S : in String) return Natural;
-
-  end Hash_Support;
-
-  with Hash_Support;
-  generic package String_Hash_Tables
-    renames Hash_Tables (Key_Type => String, Hash => Hash_Support.Hash_String);
-
-and then, a hash table package with string keys can be gotten simply by
-
-  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 packages
 ---------------------------------------------------
 
-Again, consider a generic hash table package, but this time using a signature
+Consider a hash table container abstraction using a signature
 package for the key type:
 
   generic
@@ -327,8 +222,14 @@
   package String_Keys is
      new Hashable (Key_Type => String, Hash => Hash_Support.Hash_String);
 
-  generic package String_Hash_Tables
-    renames Hash_Tables (Keys => String_Keys);
+  generic
+     with package Keys is new Hashable (<>) else 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:
 
@@ -342,8 +243,8 @@
 An example for defaults for generic formal "in out" objects
 -----------------------------------------------------------
 
-The motivating example for case #4; i.e. default values for generic formal
-"in out" objects; is the storage pool parameter often found in container
+The motivating example for default values for generic formal
+"in out" objects is the storage pool parameter often found in container
 libraries:
 
   generic
@@ -392,14 +293,12 @@
   package Lists is
      ...
 
-I'll leave open what "The_Default_Pool" actually might be; on GNAT, a possible
-working implementation might be a pre-written pool that just uses the standard
-pool of some arbitrary access type. (Not right in a strict sense, but this is
-indeed a way that works -- on GNAT, at least.) See also my other proposal on
-"standard storage pool".
+[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.]
 
-But anyway, with defaults for generic formal "in out" objects, an instantiation
-of this list package can be as simple as
+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);
 
@@ -407,77 +306,6 @@
 use the package without extra hassles, while experienced or concerned users
 still have the possibility to provide their own storage pool.
 
-An illegal example for #4 (default for generic formal "in out" object):
-
-  declare
-     type Ptr is access Integer;
-
-     procedure Free is new Ada.Unchecked_Deallocation (Integer, Ptr);
-
-     P : Ptr := new Integer'(42);
-
-     generic
-        X : in out Integer := P.all;
-     function Foo return Natural;
-
-     function Foo is
-     begin
-        return abs (X);
-     end Foo;
-
-  begin
-     Free (P);
-     declare
-        function Bar is new Foo;
-     begin
-        Ada.Text_IO.Put_Line (Natural'Image (Bar));
-     end;
-  end;
-
-However, I do *not* consider this case a showstopper for the proposal,
-because equally illegal stuff can already be done using a default value
-for a generic formal "in" object:
-
-  declare
-     type Ptr is access Integer;
-
-     procedure Free is new Ada.Unchecked_Deallocation (Integer, Ptr);
-
-     P : Ptr := new Integer'(42);
-
-     generic
-        X : in Ptr := P;
-     function Foo return Natural;
-
-     function Foo is
-     begin
-        return abs (X.all);
-     end Foo;
-
-  begin
-     Free (P);
-     declare
-        function Bar is new Foo;
-     begin
-        --  Free (P);
-        Ada.Text_IO.Put_Line (Natural'Image (Bar));
-     end;
-  end;
-
-(If the first call to "Free" is commented out, and the second one commented
-in, the effects are even more devastating. Try this with GNAT! [On Win NT,
-I get a Constraint_Error with the first "Free" (that's ok), while the
-program prints "0" with the second one (brrr!)]. That's not a critique of
-GNAT, but shows that stupid things can already be done.)
-
-In summary, I think the proposed additions would significantly enhance
-the capabilities of generics in Ada and be very useful for designing truly
-general and powerful generic abstractions that still could be easily
-instantiated in simple cases (because any generic parameters for advanced
-features would have sensible defaults). I also believe that these new defaults
-incur only a small to moderate implementation cost for compilers (although,
-me not being an Ada compiler guru, I might be mistaken).
-
 !ACATS test
 
 !appendix
@@ -511,5 +339,77 @@
 problem (if I did, I wouldn't have planned to introduce the idea).
 
 I'm not sure about the syntax, but that just carries over from CLA.
+
+****************************************************************
+
+From the minutes of the 16th ARG meeting (Vienna, Austria):
+
+Pascal argues that having such default just makes the code more obscure.
+
+Tucker counters that we have defaults for other things, why should these be
+limited to just objects and subprograms?
+
+Tucker notes that use is a bad choice, because you could leave out a semicolon
+and it would still be legal syntax. We tried hard to avoid that in Ada.
+
+We could invent a new keyword ("default" is suggested). Another suggestion
+(using existing keywords) is until others.
+
+The generic renaming proposal can be implemented with a generic skin package.
+It also appears very complex and messy to implement. We take a straw vote on
+dropping the generic renames part of the proposal, which passes easily: 6-0-2.
+This effectively means "No action" on part 3 of the proposal.
+
+Pascal wonders if we should we support <> defaults on this? John replies that
+<> defaults are a mess, we don't want to expand this further.
+
+Tucker notes that it is odd that in out would allow a default here, and not in
+subprograms. Randy comments that we could fix subprograms, too. There is no
+support for that from the group. However, Pascal notes that in out formal
+objects are really renames, the syntax is misleading.
+
+We take a straw vote on keeping the AI alive. It passes, 4-2-2.
+
+****************************************************************
+
+Editor's notes:
+
+The syntax of defaults for types is problematical. Here are some of the ideas
+I considered:
+
+generic
+   type Item_Type is private;
+   type Item_Count is range <> use Natural; -- Bad because
+					    -- type Item_Count is range <>; use Natural;
+					    -- is also legal.
+package Lists is
+
+generic
+   type Item_Type is private;
+   type Item_Count is range <> default Natural; -- 'Default' is a new keyword.
+package Lists is
+
+generic
+   type Item_Type is private;
+   type Item_Count is range <> := Natural;
+package Lists is
+
+generic
+   type Item_Type is private;
+   type Item_Count is range <> until others Natural;
+package Lists is
+
+generic
+   type Item_Type is private;
+   type Item_Count is range <> else Natural;
+package Lists is
+
+generic
+   type Item_Type is private;
+   type Item_Count is range <> else use Natural;
+package Lists is
+
+I've tested all of these in the Janus/Ada grammar using our LALR(1) parser
+generator, and all of them work (no conflicts).
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent