CVS difference for ai12s/ai12-0212-1.txt

Differences between 1.10 and version 1.11
Log of other versions for file ai12s/ai12-0212-1.txt

--- ai12s/ai12-0212-1.txt	2018/03/02 05:05:52	1.10
+++ ai12s/ai12-0212-1.txt	2018/03/28 00:45:14	1.11
@@ -1,13 +1,14 @@
-!standard 4.3.5(0)                                  18-03-01  AI12-0212-1/05
+!standard 4.3.5(0)                                  18-03-13  AI12-0212-1/06
 !class Amendment 16-12-27
 !status work item 17-06-10
 !status received 16-06-12
 !priority Low
 !difficulty Hard
-!subject Container aggregates
+!subject Container aggregates; generalized array aggregates
 !summary
 
-Add aggregate syntax to construct container instances.
+Add aggregate syntax to construct container instances.  Allow
+container iterators in array aggregates.
 
 !problem
 
@@ -69,7 +70,7 @@
 The function or constant "Empty_Set" is one of the two (or three) things
 you specify in the Aggregate aspect (the "Empty" component of the
 Aggregate aspect), the procedure "Include" is the other (the
-"Add_Positional" component of the Aggregate aspect).
+"Add_Unnamed" component of the Aggregate aspect).
 
 Positional container aggregates are good for defining simple container
 instances, but often, you might want to derive one container from
@@ -158,7 +159,7 @@
            Iterator_Element  => Element_Type,
            --  this is new
            Aggregate         => (Empty => Empty_Set,
-                                 Add_Positional => Include);
+                                 Add_Unnamed => Include);
 
 For containers such as maps, an Add_Named component of the Aggregate
 aspect would be specified, to enable a usage such as:
@@ -186,10 +187,13 @@
 
 So, to summarise:
 * New aspect on types specifying an empty default, plus an
-  Add_Positional, and either an Add_Named procedure or Assign_Indexed
-  procedure (with a New_Indexed function to go with it).
-* Extend aggregate syntax to trigger these
+  Add_Named procedure, or an Add_Unnamed procedure and/or an
+  Assign_Indexed procedure (with a New_Indexed function to go with it).
+* Extend aggregate syntax to support these based on the expected type
 
+We also provide wording to allow container iterators within an
+array aggregate.
+
 !wording
 
 Modify 13.1.1(5/3):
@@ -223,6 +227,68 @@
   record type, [or ]record extension{, or other composite type with the
   Aggregate aspect specified}.
 
+---- wording for adding container iterators to array aggregates:
+
+Replace 4.3.3(5.1/5):
+
+   iterated_component_association ::=
+       for defining_identifier in discrete_choice_list => expression
+
+with:
+
+   iterated_component_association ::=
+       for defining_identifier in discrete_choice_list => expression
+     | for iterator_specification => expression
+
+Add after 4.3.3(17/5):
+
+  Either all or none of the array_component_associations of an
+  array_component_association_list shall be iterated_component_associations
+  with an iterator_specification.
+
+Add 4.2.3(20) as follows:
+  For an array_aggregate that contains only
+  array_component_associations that are iterated_component_associations
+  with iterator_specifications, evaluation proceeds in two steps:
+
+  1. Each iterator_specification is elaborated (in an arbitrary order)
+     and an iteration is performed solely to determine a count of
+     the number of values produced by the iteration; all of these counts are
+     combined to determine the overall length of the array, and
+     ultimately the bounds of the array (defined below);
+
+  2. A second iteration is performed for each of the iterator_specifications,
+     in the order given in the aggregate, and for each value produced,
+     the associated expression is evaluated, its value is converted to
+     the component subtype of the array type, and used to define the
+     value of the next component of the array starting at the low bound
+     and proceeding sequentially toward the high bound.
+
+Modify 4.2.3(21) as follows:
+
+  The evaluation of [an] {any other} array_aggregate of a given
+  array type proceeds in two steps:
+
+Modify 4.3.3(23.2/5)
+
+  During an evaluation of the expression of an
+  iterated_component_association {with a discrete_choice_list}, the
+  value of the corresponding index parameter is that of the
+  corresponding index of the corresponding array component.  {During an
+  evaluation of the expression of an iterated_component_association
+  with an iterator_specification, the value of the loop parameter
+  of the iterator_specification is the value produced by the iteration.}
+
+Add after 4.3.3(26):
+   * For a named_array_aggregate containing only
+     iterated_component_associations with an iterator_specification, the
+     lower bound is determined as for a positional_array_aggregate without
+     an OTHERS choice, and the upper bound is determined from the lower
+     bound and the total number of values produced by the iteration(s);
+
+----  end of wording for array aggregate enhancement ----
+
+
 Add new section:
 
 4.3.5 Container Aggregates
@@ -244,15 +310,15 @@
     This aspect is an aggregate of the form:
 
       (Empty => name[,
-       Add_Positional => /procedure_/name][,
        Add_Named => /procedure_/name][,
+       Add_Unnamed => /procedure_/name][,
        New_Indexed => /function_/name,
        Assign_Indexed => /procedure_/name])
 
-    A /procedure_/name shall be specified for at least one of
-    Add_Positional, Add_Named, or Assign_Indexed.  A /procedure_/name shall
-    be specified for at most one of Add_Named or Assign_Indexed.  Either both
-    or neither of New_Indexed and Assign_Indexed shall be specified.
+    A /procedure_/name shall be specified for at least one of Add_Named,
+    Add_Unnamed, or Assign_Indexed.  If Add_Named is specified, neither
+    Add_Unnamed nor Assign_Indexed shall be specified.  Either both or
+    neither of New_Indexed and Assign_Indexed shall be specified.
 
 Name Resolution Rules
 
@@ -268,7 +334,7 @@
       to estimate the number of elements that the iterator will produce,
       but it is not required to do so.
 
-    The /procedure_/name specified for Add_Positional, if any, shall
+    The /procedure_/name specified for Add_Unnamed, if any, shall
     denote a procedure that has two parameters, the first an IN OUT
     parameter of type T, and the second an IN parameter of some
     nonlimited type, called the /element type/ of T.
@@ -288,9 +354,8 @@
     type/ of T.  In the case of Assign_Indexed, the key type shall be the
     same type as that of the parameters of New_Indexed.
 
-    If both Add_Positional and either Add_Named or Assign_Indexed are
-    specified, the final parameters shall be of the same type -- the
-    element type of T.
+    If both Add_Unnamed and Assign_Indexed are specified, the final
+    parameters shall be of the same type -- the element type of T.
 
 Syntax
 
@@ -307,10 +372,13 @@
      container_element_association {, container_element_association}
 
    container_element_association ::=
-     key_expression_list => expression
+     key_choice_list => expression
+   | key_choice_list => <>
    | iterated_element_association
+
+   key_choice_list ::= key_choice {| key_choice}
 
-   key_expression_list ::= /key_/expression {| /key_/expression}
+   key_choice ::= /key_/expression | discrete_range
 
    iterated_element_association ::=
       for loop_parameter_specification[, /key_/expression] => expression
@@ -323,51 +391,64 @@
 expression of a container_aggregate is the element type of the expected
 type.
 
-The expected type for a positional_container_aggregate shall have an
-Aggregate aspect that includes a specification for an Add_Positional
-procedure or an Assign_Indexed procedure.  The expected type for a
-named_container_aggregate that has one or more /key_/expressions shall
-have an Aggregate aspect that includes a specification for the Add_Named
-or Assign_Indexed procedure.  The expected type for each such
-/key_/expression is the key type of the expected type. [Redundant: An
-empty_container_aggregate may be used with any expected type that has an
-Aggregate aspect.]
+The expected type for a /key_/expression, or a discrete_range of a
+key_choice, is the key type of the expected type of the aggregate.
 
 Legality Rules
 
-If the expected type T of an aggregate specifies an Assign_Indexed
-procedure in its Aggregate aspect, then the aggregate is called an
-/indexed aggregate/ if there is no Add_Positional procedure specified,
-or if the aggregate is a named_container_aggregate with a
-container_element_association that has a key_expression_list,
-or that has a loop_parameter_specification.  The key type of an indexed
-aggregate is also called the /index type/ of the aggregate.
+The expected type for a positional_container_aggregate shall have an
+Aggregate aspect that includes a specification for an Add_Unnamed
+procedure or an Assign_Indexed procedure. The expected type for a
+named_container_aggregate that contains one or more
+iterated_element_associations with a /key_/expression shall have an
+Aggregate aspect that includes a specification for the Add_Named
+procedure.  The expected type for a named_container_aggregate that
+contains one or more key_choice_lists shall have an Aggregate aspect
+that includes a specification for the Add_Named or Assign_Indexed
+procedure. [Redundant: (An empty_container_aggregate can be of any type
+with an Aggregate aspect.)]
+
+A non-empty container aggregate is called an /indexed aggregate/ if the
+expected type T of the aggregate specifies an Assign_Indexed procedure
+in its Aggregate aspect, and either there is no Add_Unnamed procedure
+specified for the type, or the aggregate is a named_container_aggregate
+with a container_element_association that contains a key_choice_list
+or a loop_parameter_specification.  The key type of an indexed aggregate
+is also called the /index type/ of the aggregate.
+
+A container_element_association with a <> rather than an expression,
+or with a key_choice that is a discrete_range, is permitted only in
+an indexed aggregate.
+  AARM Reason: Only an element of an indexed aggregate can be left
+  uninitialized, because the compiler can simply omit producing an
+  Assign_Indexed operation for the given index.  For other kinds of
+  aggregates, there are no operations that add an element without giving
+  it a value. Note that to be consistent with array aggregates, we do
+  not support specifying <> in an iterated_element_association.
 
 For an iterated_element_association without a /key_/expression, if the
-expected type T of the aggregate does not specify an Add_Positional
-procedure in its Aggregate aspect, or if the aggregate is an indexed
-aggregate, then the type of the loop parameter of the
-iterated_element_association shall be the same as the key type of T.
+aggregate is an indexed aggregate or the expected type of the
+aggregate specifies an Add_Named procedure in its Aggregate aspect, then
+the type of the loop parameter of the iterated_element_association shall
+be the same as the key type of the aggregate.
   AARM Ramification: If there is a /key_/expression in an
   iterated_element_association, it determines the key of each added
-  key/value pair, rather than the loop parameter.  If there is no
-  /key_/expression, the loop parameter itself is used as the key,
-  and for Assign_Indexed, the iterated_element_association must
-  be over a contiguous discrete range.
-
-For a named_container_aggregate that is an indexed aggregate,
-all container_element_associations shall either have a
-key_expression_list or have a loop_parameter_specification.
+  key/value pair, rather than the loop parameter.  But if there is no
+  /key_/expression, the loop parameter itself is used as the key.
+
+For a named_container_aggregate that is an indexed aggregate, all
+container_element_associations shall contain either a key_choice_list,
+or a loop_parameter_specification without a /key_/expression.
 Furthermore, for such an aggregate, either:
-  * all /key_/expressions shall be static expressions, and every
+  * all key_choices shall be static expressions or static ranges, and every
     loop_parameter_specification shall have a
     discrete_subtype_definition that defines a non-null static range,
     and the set of values of the index type covered by the
-    /key_/expressions and the discrete_subtype_definitions shall form a
+    key_choices and the discrete_subtype_definitions shall form a
     contiguous range of values with no duplications; or
   * there shall be exactly one container_element_association, and if
-    it has a key_expression_list, the list shall have exactly one
-    /key_/expression.
+    it has a key_choice_list, the list shall have exactly one
+    key_choice.
       AARM Reason: The above is trying to mimic the rules for named array
       aggregates, without others.
 
@@ -377,19 +458,19 @@
 object A of the expected type T initialized as follows:
    * if the aggregate is an indexed aggregate, from the result of a call
      on the New_Indexed function; the actual parameters in this call
-     represent the first and last index of the aggregate, and are determined
-     as follows:
-      * if the aggregate is a positional_container_aggregate, the first index
+     represent the lower and upper bound of the aggregate, and are
+     determined as follows:
+      * if the aggregate is a positional_container_aggregate, the lower bound
         is the low bound of the subtype of the key parameter of the
-        Add_Indexed procedure, and the last index has a position number
-        that is the sum of the position number of the first index and
+        Add_Indexed procedure, and the upper bound has a position number
+        that is the sum of the position number of the lower bound and
         one less than the number of expressions in the aggregate;
-      * if the aggregate is a named_container_aggregate, the first index
-        is the lowest value appearing either within a key_expression_list or
-        as the low bound of a range defined by a discrete_subtype_definition
-        of a loop_parameter_specification; the last index is the highest
-        vale appearing either within a key_expression_list or as the high
+      * if the aggregate is a named_container_aggregate, the lower bound
+        is the lowest value covered by a key_choice_list or as the low
         bound of a range defined by a discrete_subtype_definition of a
+        loop_parameter_specification; the upper bound is the highest
+        value covered by a key_choice_list or is the high bound of a
+        range defined by a discrete_subtype_definition of a
         loop_parameter_specification.
    * if the aggregate is not an indexed aggregate, by assignment from the
      Empty constant, or from a call on the Empty function specified in
@@ -408,30 +489,30 @@
 The evaluation then proceeds as follows:
   * for an empty_container_aggregate, the anonymous object A is the result;
   * for a positional_container_aggregate of a type with a specified
-    Add_Positional procedure, each expression is evaluated
-    in an arbitrary order, and the Add_Positional procedure is invoked
-    in sequence with the anonymous object A as the first parameter and
-    the result of evaluating each expression as the second parameter, in
-    the order of the expressions;
+    Add_Unnamed procedure, each expression is evaluated in an arbitrary
+    order, and the Add_Unnamed procedure is invoked in sequence with the
+    anonymous object A as the first parameter and the result of
+    evaluating each expression as the second parameter, in the order of
+    the expressions;
   * for a positional_container_aggregate that is an indexed aggregate,
-    each expression is evaluated in an arbitrary
-    order, and the Assign_Indexed procedure is invoked in sequence with the
-    anonymous object A as the first parameter, the key value as the
-    second parameter, computed by starting with the low bound of the
-    subtype of the key formal parameter of the Assign_Indexed procedure and
-    taking the successor of this value for each successive expression,
-    and the result of evaluating each expression as the third parameter;
+    each expression is evaluated in an arbitrary order, and the
+    Assign_Indexed procedure is invoked in sequence with the anonymous
+    object A as the first parameter, the key value as the second
+    parameter, computed by starting with the low bound of the subtype of
+    the key formal parameter of the Assign_Indexed procedure and taking
+    the successor of this value for each successive expression, and the
+    result of evaluating each expression as the third parameter;
   * for a named_container_aggregate for a type with an Add_Named procedure
     in its Aggregate aspect, the container_element_associations are evaluated
     in an arbitrary order:
-     * for a container_element_association with a key_expression_list,
-       for each /key_/expression of the list in an arbitrary order, the
-       /key_/expression is evaluated as is the expression of the
-       container_element_association (in an arbitrary order), and the Add_Named
-       procedure is invoked with the anonymous object A as the first
-       parameter, the result of evaluating the /key_/expression as the
-       second parameter, and the result of evaluating the expression as
-       the third parameter;
+     * for a container_element_association with a key_choice_list,
+       for each key_choice of the list in an arbitrary order, the
+       key_choice is evaluated as is the expression of the
+       container_element_association (in an arbitrary order), and the
+       Add_Named procedure is invoked once for each value covered by the
+       key_choice, with the anonymous object A as the first parameter,
+       the value from the key_choice as the second parameter, and the
+       result of evaluating the expression as the third parameter;
      * for a container_element_association with an iterated_element_association,
        the iterated_element_association is elaborated, and an iteration
        is performed, and for each value of the loop parameter of the
@@ -443,28 +524,31 @@
           * otherwise, with the loop parameter as the second parameter;
    * for a named_container_aggregate that is an indexed aggregate, the
      evaluation proceeds as above for the case of Add_Named, but with
-     the Assign_Indexed procedure being invoked in its stead;
-   * for any other named_container_aggregate, the container_element_associations
-     (which are necessarily iterated_element_associations)
-     are evaluated in the order given:
+     the Assign_Indexed procedure being invoked in its stead; in the
+     case of a container_element_association with a <> rather than an
+     expression, the corresponding call on Assign_Indexed is not
+     performed, leaving the component as it was upon return from
+     the New_Indexed function;
+   * for any other named_container_aggregate, the
+     container_element_associations (which are necessarily
+     iterated_element_associations) are evaluated in the order given:
        * the iterated_element_association is elaborated, and an iteration
          is performed, and for each value of the loop parameter of the
-         iteration, the Add_Positional procedure is invoked with the
-         anonymous object A as the first parameter, and the result of
+         iteration, the Add_Unnamed procedure is invoked, with the
+         anonymous object A as the first parameter and the result of
          evaluating the expression as the second parameter.
            AARM Ramification: In this case, the value of the loop parameter
            is not directly relevant, though presumably it appears within
            the expression of the iterated_element_association.
 
-
 Examples
 
 Declarations of Set_Type, Map_Type, and Vector_Type:
 
    --  Set_Type is a set-like container type.
    type Set_Type is private
-     with Aggregate => (Empty          => Empty_Set,
-                        Add_Positional => Include);
+     with Aggregate => (Empty       => Empty_Set,
+                        Add_Unnamed => Include);
    function Empty_Set return Set_Type;
 
    subtype Small_Natural is Natural range 0..1000;
@@ -473,8 +557,8 @@
 
    --  Map_Type is a map-like container type.
    type Map_Type is private
-     with Aggregate =>  (Empty      => Empty_Map,
-                         Add_Named  => Add_To_Map);
+     with Aggregate =>  (Empty     => Empty_Map,
+                         Add_Named => Add_To_Map);
 
    procedure Add_To_Map (M : in out Map_Type; Key : Integer; Value : String);
 
@@ -483,7 +567,7 @@
    --  Vector_Type is an extensible array-like container type.
    type Vector_Type is private
       with Aggregate => (Empty          => Empty_Vector,
-                         Add_Positional => Append_One,
+                         Add_Unnamed    => Append_One,
                          New_Indexed    => New_Vector,
                          Assign_Indexed => Assign_Element)
 
@@ -563,44 +647,9 @@
    S := (for Item in 1 .. 5 => Item,
          for Item in 1 .. 5 => -Item);
 
-   --  Is (mostly, assuming set semantics) equivalent to
+   --  Is equivalent (assuming set semantics) to
    S := (for Item in -5 .. 5 when Item /= 0 => Item);
 
-   --  A set aggregate with more than one item_selector (a TBD AI)
-   S := (for X in 1 .. 10 => for Y in -1 .. 1 when Y /= 0 => X * Y);
-
-   --  is equivalent to
-   S := Empty_Set;
-   for X in 1 .. 10 loop
-      for Y in -1 .. 1 loop
-         if Y /= 0 then
-            Include (S, X * Y);
-         end if;
-      end if;
-   end if;
-
-   --  An example that combines all aspects of the grammar
-   S := (for Customer of Customer_Database when not Customer.Poor =>
-           Customer.Name,
-         for Manager of Managers =>
-            for Staff of Manager.Minions when Staff.Performance >= 3.0 =>
-              Staff.First_Name & Staff.Last_Name);
-
-   --  Is equivalent to
-   S := Empty_Set;
-   for Customer of Customer_Database loop
-      if not Customer.Poor =>
-         Include (S, Customer.Name);
-      end if;
-   end loop;
-   for Manager of Managers loop
-      for Staff of Manager.Minions loop
-         if Staff.Performance => 3.0 then
-            Include (S, Staff.First_Name & Staff.Last_Name);
-         end if;
-      end loop;
-   end loop;
-
    --  Example aggregates using Map_Type
    M : Map_Type;
 
@@ -710,7 +759,7 @@
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
            Aggregate         => (Empty          => Empty_Vector,
-                                 Add_Positional => Append_One,
+                                 Add_Unnamed    => Append_One,
                                  New_Indexed    => New_Vector,
                                  Assign_Indexed => Replace_Element);
 
@@ -731,8 +780,8 @@
            Variable_Indexing => Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Aggregate         => (Empty          => Empty_List,
-                                 Add_Positional => Append);
+           Aggregate         => (Empty       => Empty_List,
+                                 Add_Unnamed => Append);
 
 A.18.5 The Generic Package Containers.Hashed_Maps
 
@@ -766,8 +815,8 @@
       with Constant_Indexing => Constant_Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Aggregate         => (Empty          => Empty_Set,
-                                 Add_Positional => Include);
+           Aggregate         => (Empty       => Empty_Set,
+                                 Add_Unnamed => Include);
 
 A.18.9 The Generic Package Containers.Ordered_Sets
 
@@ -777,17 +826,31 @@
       with Constant_Indexing => Constant_Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Aggregate         => (Empty          => Empty_Set,
-                                 Add_Positional => Include);
+           Aggregate         => (Empty       => Empty_Set,
+                                 Add_Unnamed => Include);
 
 !discussion
 
 See !proposal for most of the discussion.  Here we discuss some rejected
 alternatives or additions.
 
-We plan to generalize array aggregates as well to allow arbitrary
-iterators, probably in a separate AI, or perhaps a subsequent revision
-of this one.  Originally we were concerned about making this
+We originally used "Add_Positional" instead of "Add_Unnamed" in the
+Aggregate aspect, but that created confusion because the Add_Unnamed
+operation is used for both named and positional aggregates.  Add_Unnamed
+is used for named aggregates when they use a container iterator without
+a specified key-expression.
+
+Before we had Assign_Indexed, we allowed both Add_Unnamed and Add_Named
+for a single type.  But in fact, it really doesn't make much sense
+to allow both, since what would be the "default" value of the key
+if you were to apply Add_Unnamed to something like a "map" container.
+On the other hand, both Add_Unnamed and Assign_Indexed
+can be specified for the same (vector-like) type, since the container
+maintains a high bound for its index type, so Add_Unnamed can by default
+extend the vector and assign the new last element.
+
+We include above a generalization of array aggregates to allow container
+iterators.  Originally we were concerned about making this
 generalization, because to determine the size of the array to create,
 you will need to execute the iterator until it ends. We initially
 presumed you would have to save all of the values somewhere, create the
@@ -2066,7 +2129,7 @@
 From: Randy Brukardt
 Sent: Tuesday, February 27, 2018  5:56 PM
 
-> Here is an update, with Jeff's corrections. 
+> Here is an update, with Jeff's corrections.
 
 I'm just getting around to reading this. Comments:
 
@@ -2133,98 +2196,98 @@
 ---
 
 That's all I have at this point.
-  
+
 ****************************************************************
 
 From: Tucker Taft
 Sent: Wednesday, February 28, 2018  6:05 AM
 
->> Here is an update, with Jeff's corrections. 
-> 
+>> Here is an update, with Jeff's corrections.
+>
 > I'm just getting around to reading this. Comments:
-> 
-> For some reason, you numbered this "version 5" (and the previous one 
-> "version 4"), but there never was a version 3. So you are off by one 
+>
+> For some reason, you numbered this "version 5" (and the previous one
+> "version 4"), but there never was a version 3. So you are off by one
 > for the version numbers. (This one was posted as version /04.)
 
 Sorry about that.
 
-> 
+>
 > ---
-> 
-> The syntax for aspect Aggregate separates the parts with commas, but 
-> the examples use semicolons. (I'd expect commas to be consistent with 
-> similar syntax elsewhere in Ada, but whatever it is should be 
+>
+> The syntax for aspect Aggregate separates the parts with commas, but
+> the examples use semicolons. (I'd expect commas to be consistent with
+> similar syntax elsewhere in Ada, but whatever it is should be
 > consistent.)
 
 Oops.  Definitely meant to use "," since we want these to look like aggregates.
-> 
+>
 > ---
-> 
-> 13.1.1 gives a list of things that can be an aspect. This new syntax 
-> for aspect Aggregate is not one of those things. Note that when I was 
-> faced with a similar issue for aspect Stable_Properties, I extended 
-> the syntax in 13.1.1. We do have a blanket "alternative rules may 
-> apply" statement, but it would be best if we made all of the 
-> language-defined aspects as consistent as possible. One possibility 
-> would be to make "aggregate" a syntactic choice here, and then redo 
+>
+> 13.1.1 gives a list of things that can be an aspect. This new syntax
+> for aspect Aggregate is not one of those things. Note that when I was
+> faced with a similar issue for aspect Stable_Properties, I extended
+> the syntax in 13.1.1. We do have a blanket "alternative rules may
+> apply" statement, but it would be best if we made all of the
+> language-defined aspects as consistent as possible. One possibility
+> would be to make "aggregate" a syntactic choice here, and then redo
 > Stable_Properties in terms of that (stable properties needing a list, for
 > which positional aggregate syntax would be fine).
-> 
+>
 > Maybe we should do that here, maybe in another AI.
 
 I would do it here.  Interdependent AIs are a bit of a pain.
- 
+
 > ---
-> 
-> You and I have swapped positions on the iterated choices. :-) I now 
-> think that they ought to be treated like others (which isn't allowed 
+>
+> You and I have swapped positions on the iterated choices. :-) I now
+> think that they ought to be treated like others (which isn't allowed
 > here) -- that is, they can appear in positional aggregates, but only if they
-> appear last. That's the only way to make vector and array aggregates near 
-> identical, because the iterated choice (except for the "traditional" 
+> appear last. That's the only way to make vector and array aggregates near
+> identical, because the iterated choice (except for the "traditional"
 > discrete range
-> one) doesn't provide the indexes needed for a named array aggregate. 
-> And all of them (again except for the "traditional" discrete range 
-> one) can't appear in a named array aggregate without a key expression 
+> one) doesn't provide the indexes needed for a named array aggregate.
+> And all of them (again except for the "traditional" discrete range
+> one) can't appear in a named array aggregate without a key expression
 > (which is really the index expression for an array aggregate).
 
 I am not really following this.  Could you give an example or two?
 
-> We probably need to figure out the array aggregate rules for this, 
-> because it doesn't do for container aggregates and array aggregates to 
+> We probably need to figure out the array aggregate rules for this,
+> because it doesn't do for container aggregates and array aggregates to
 > work very differently in this case (or any case, when it comes to vector
 > aggregates).
-> 
+>
 > ---
-> 
-> Erhard complained about using "," to represent sequentiality -- but 
-> this is an aggregate, and the choices can be evaluated in an arbitrary 
-> order. Ergo, it ISN'T representing sequentiality, just proximity. ";" 
+>
+> Erhard complained about using "," to represent sequentiality -- but
+> this is an aggregate, and the choices can be evaluated in an arbitrary
+> order. Ergo, it ISN'T representing sequentiality, just proximity. ";"
 > (which does represent sequentiality) would be wrong.
 
 I agree -- "," is used to separate elements in an aggregate, whether they are
 iterated component associations or simple "<range> => value" associations.
 
-> 
+>
 > ---
-> 
-> If we want array and vector aggregates to really be similar, then we 
-> need a named vector aggregate option. This would best be somewhat 
-> separate from the map aggregate, so that the requirements on named 
+>
+> If we want array and vector aggregates to really be similar, then we
+> need a named vector aggregate option. This would best be somewhat
+> separate from the map aggregate, so that the requirements on named
 > array and vector aggregates are identical.
-> 
-> Ergo, I'd suggest a third choice (maybe "Add_Indexed") which requires 
-> that the key type is discrete; then choices that are ranges would be 
-> allowed, and non-overlap checking (with the only one dynamic choice 
-> rule) could be enforced. Essentially, the legality rules would match 
-> an array aggregate sans "others" (no others as there is no sane way to 
+>
+> Ergo, I'd suggest a third choice (maybe "Add_Indexed") which requires
+> that the key type is discrete; then choices that are ranges would be
+> allowed, and non-overlap checking (with the only one dynamic choice
+> rule) could be enforced. Essentially, the legality rules would match
+> an array aggregate sans "others" (no others as there is no sane way to
 > get an applicable index constraint). (The dynamic rules would be essentially
 > the same as Add_Named).
 
 I agree -- Add_Indexed sounds useful, and should be distinct from Add_Named.
- 
+
 > ---
-> 
+>
 > That's all I have at this point.
 
 Thanks.  I'll try to send out a quick update, with at least some of this.
@@ -2251,7 +2314,7 @@
 aggregate are as similar in functionality as we can make them.
 
 Note that since delta aggregates only work for named notation, such container
-aggregates would only be meaningful for "Add_Named" and "Add_Indexed" cases. 
+aggregates would only be meaningful for "Add_Named" and "Add_Indexed" cases.
 Meaning that Lists and Sets couldn't use them -- annoying, but understandable.
 
 ****************************************************************
@@ -2260,25 +2323,25 @@
 Sent: Wednesday, February 28, 2018  6:08 PM
 
 ...
-> > You and I have swapped positions on the iterated choices. :-) I now 
+> > You and I have swapped positions on the iterated choices. :-) I now
 > > think that they ought to be treated like others (which isn't allowed
-> > here) -- that is, they can appear in positional aggregates, but only 
+> > here) -- that is, they can appear in positional aggregates, but only
 > > if they appear last.
-> > That's the only way to make vector and array aggregates near 
+> > That's the only way to make vector and array aggregates near
 > > identical, because the iterated choice (except for the "traditional"
 > > discrete range
-> > one) doesn't provide the indexes needed for a named array aggregate. 
+> > one) doesn't provide the indexes needed for a named array aggregate.
 > > And all of them (again except for the "traditional" discrete range
-> > one) can't appear in a named array aggregate without a key 
+> > one) can't appear in a named array aggregate without a key
 > > expression (which is really the index expression for an array aggregate).
-> 
+>
 > I am not really following this.  Could you give an example or two?
 
-Array aggregates in Ada have some restrictions on them in order to ease 
+Array aggregates in Ada have some restrictions on them in order to ease
 implementation, for instance the only dynamic part of a positional aggregate
 has to be the last one, and there can only be a single dynamic part in a named
 aggregate. I've been assuming that we'd want to preserve some version of this
-going forward (so we aren't allowing arbitrary dynamic iterators in array 
+going forward (so we aren't allowing arbitrary dynamic iterators in array
 aggregates) -- if we wanted to relax these sorts of restrictions, we
 definitely need to do that generally and not just in this one special case.
 (The effort to implement is about the same for all of these cases.)
@@ -2288,7 +2351,7 @@
 they *can't* be a named aggregate). For example:
 
       Some_List : ... -- A list container of Natural.
-      
+
       type Some_Array is array (Positive range <>) of Natural;
 
       Agg1 : Some_Array := (for E of Some_List => E);
@@ -2300,7 +2363,7 @@
           -- This is currently a named aggregate, since it is dynamic it can
           -- be the only choice here.
       Agg3 : Some_Array := (for E of Agg1 => E;
-          -- This could go either way, as the indexes could be implied from 
+          -- This could go either way, as the indexes could be implied from
           -- those of Agg1, or ignored (since they're not explicit)
       Agg4 : Some_Array := (for C in Some_List.Iterator => Some_List.Element(C));
           -- Has to be positional, again there is no source for array indexes.
@@ -2322,10 +2385,10 @@
 So, we either have to treat these iterators similarly to "others" and allow
 them (only?) in positional aggregates, or treat them exactly like "others"
 and allow them only when the bounds come from context. I preferred the first
-of these when I thought about it, because it would likely to be annoying to 
+of these when I thought about it, because it would likely to be annoying to
 have to pre-figure the bounds (and declare an appropriate subtype) when these
 aggregates are passed as parameters (with unconstrained formal types) or when
-used in preconditions/postconditions (declaring an bounded subtype might not 
+used in preconditions/postconditions (declaring an bounded subtype might not
 be possible if other parameters are involved).
 
 However this works for arrays, container aggregates ought to be similar, just
@@ -2339,14 +2402,14 @@
 
 Here is a new version [this is version /05 of the AI - ED.] that incorporates
 Randy's idea of "indexed" aggregates,
-where they require a contiguous no-duplicates range of indices in a named 
+where they require a contiguous no-duplicates range of indices in a named
 aggregate.  This was more work than I originally anticipated, because we need
 to create the object in advance with bounds determined from the names, and
 then assign individual values.  I introduced the term "indexed aggregates" to
 avoid having to keep repeating the circumstances under which the new
 New_Indexed/Assign_Indexed routines would be invoked.
 
-The net result of this is that now you can use named aggregates with Vectors, 
+The net result of this is that now you can use named aggregates with Vectors,
 and get the same level of checking as is provided for a named array aggregate
 (full coverage, etc.).
 
@@ -2363,18 +2426,18 @@
 Sent: Thursday, March 1, 2018  10:19 PM
 
 ...
-> I did *not* try to incorporate Randy's idea of positional aggregate 
-> with a single iterated-element-association at the end.  It seems easy 
-> enough to require the whole aggregate to be named in that case.  A 
-> mixture of positional and named just seemed too weird, except for the 
-> special case of "others => blah" which depends on the "applicable 
+> I did *not* try to incorporate Randy's idea of positional aggregate
+> with a single iterated-element-association at the end.  It seems easy
+> enough to require the whole aggregate to be named in that case.  A
+> mixture of positional and named just seemed too weird, except for the
+> special case of "others => blah" which depends on the "applicable
 > index constraint"
 > notion that doesn't generalize to container aggregates.
 
 But then you can't use them at all in "Add_Indexed" or array aggregates,
 because they do not have any way to have bounds. Unless you plan to define
 a whole new set of bounds rules -- and even that would have to limit them to
-one iterator per aggregate (I sure hope we're not planning to dump the "one 
+one iterator per aggregate (I sure hope we're not planning to dump the "one
 dynamic choice" rule only in this weird case). That doesn't seem to be the way
 you wanted to go -- but perhaps you've decided to abandon iterators in
 aggregates except in the map case???
@@ -2394,7 +2457,7 @@
 >  procedure (with a New_Indexed function to go with it).
 >* Extend aggregate syntax to trigger these
 
-This second bullet seems like 1/2 of a thought. "trigger these" what? There 
+This second bullet seems like 1/2 of a thought. "trigger these" what? There
 doesn't seem to be any extension of aggregate syntax needed here (that should
 happen in array aggregates, as previously discussed, and should really happen
 first so we don't end up with a hodge-podge of rules).
@@ -2405,7 +2468,7 @@
 >  object, a value, an expression{, an aggregate}, a subprogram, or some
 >  other kind of entity. If the aspect_mark identifies:
 
-Don't we need to add "aggregate" to the syntax? It's rather confusing to have 
+Don't we need to add "aggregate" to the syntax? It's rather confusing to have
 it implicit as part of expression and we already have "name" which also
 completely overlaps with "expression".
 
@@ -2421,5 +2484,813 @@
 inverse of the usual problem.) I have to wonder if we need all of the
 equivalences in the RM (as opposed to in the !examples section of the AI). But
 we do need *some* examples in the RM.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, March 2, 2018   3:00 AM
+
+> ...
+>> I did *not* try to incorporate Randy's idea of positional aggregate
+>> with a single iterated-element-association at the end.  It seems easy
+>> enough to require the whole aggregate to be named in that case.  A
+>> mixture of positional and named just seemed too weird, except for the
+>> special case of "others => blah" which depends on the "applicable
+>> index constraint"
+>> notion that doesn't generalize to container aggregates.
+>
+> But then you can't use them at all in "Add_Indexed" or array
+> aggregates, because they do not have any way to have bounds.
+
+Not sure what you mean by "them" in "can't use them."  Did you mean vectors?
+The proposal does support them, but with a precondition that the low bound
+matches Index_Type'First.
+
+> Unless you plan to define a
+> whole new set of bounds rules -- and even that would have to limit
+> them to one iterator per aggregate (I sure hope we're not planning to
+> dump the "one dynamic choice" rule only in this weird case). That
+> doesn't seem to be the way you wanted to go -- but perhaps you've
+> decided to abandon iterators in aggregates except in the map case???
+
+Did you look at the proposal?  If so, please clarify your concern.  If not,
+please take a look at the proposal for how Vectors would be supported, and if
+you have comments on that, let me know.  Clearly some array-like containers
+might allow arbitrary bounds, and others, such as Vector, would require the
+same low bound for all objects of a given type.  I presumed a precondition
+could be used to enforce the vector-like requirement of a fixed low bound.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, March 2, 2018  6:01 PM
+
+...
+> Not sure what you mean by "them" in "can't use them."  Did you mean
+> vectors?  The proposal does support them, but with a precondition that
+> the low bound matches Index_Type'First.
+
+"them" = iterated-element-association.
+
+I've mostly been thinking about how they fit into the array aggregate rules.
+Once that is figured out, then one can use similar rules for container
+aggregates. Starting with the containers is ass-backwards -- that's a blank
+slate, whereas with the arrays they have to be fit into existing wording.
+
+As I've previously noted, I do not want incentives to use one kind of type
+over the other (in either direction), so anything available in the containers
+also has to be available in array aggregates.
+
+Aside: The first paragraph of the Legality Rules just provides definitions.
+Shouldn't that be in Static Semantics?
+
+> > Unless you plan to define a
+> > whole new set of bounds rules -- and even that would have to limit
+> > them to one iterator per aggregate (I sure hope we're not planning
+> > to dump the "one dynamic choice" rule only in this weird case). That
+> > doesn't seem to be the way you wanted to go -- but perhaps you've
+> > decided to abandon iterators in aggregates except in the map case???
+>
+> Did you look at the proposal?  If so, please clarify your concern.  If
+> not, please take a look at the proposal for how Vectors would be
+> supported, and if you have comments on that, let me know.
+
+The idea that a named aggregate uses Add_Positional is bizarre. It works here
+because of the blank-slate issue, but it will not work with arrays.
+
+Well, actually it doesn't work that well here. You now have the possibility of
+mixed keyed and unkeyed choices (because you are treating an iterator as named
+even though it doesn't provide any). For instance:
+
+    A_Map := ("Tuck" => True, "Randy" => False, for E of Some_Bits => E);
+
+Assuming that both Add_Named and Add_Positional are supported, this
+"aggregate" would be implemented with a mix of "named" and "positional"
+inserts - that seems like madness. (A type supporting both could make sense
+for a keyed set, for instance.)
+
+It's also bizarre (and violates my rule above), that you can write:
+
+    A_Map := (for E of Some_Bits => E, for E of Some_Other_Bits => E);
+
+for a map, but it's illegal for an array or vector.
+
+And it's bizarre that you can write:
+
+    A_List := (for I in 1..1 => True, for I in 1..1 => False, for E of Some_Bits => E);
+
+but you're not allowed to write:
+
+    A_List := (True, False, for E of Some_Bits => E);
+
+(since lists are only positional, and the only named choices that a positional
+type can write are iterators). If we adopted these rules as-is, I predict
+you'll see the above pretty often.
+
+> Clearly some array-like containers might allow arbitrary bounds, and
+> others, such as Vector, would require the same low bound for all
+> objects of a given type.  I presumed a precondition could be used to
+> enforce the vector-like requirement of a fixed low bound.
+
+I've said repeatedly that I would want to see how these iterators are
+integrated into the array containers before worrying about anything else.
+That makes the most sense as positional, at the very least in terms of how the
+bounds are determined, the legality rules on the indexes are checked, and the
+like. If you try to add them to named aggregates, you'll need to make a
+special case for every rule that applies to such an aggregate ("unless it
+contains an iterator, in which case the bounds are completely different").
+
+If they end up being part of positional aggregates for arrays (definitely the
+easiest way to deal with them), then they ought to be handled similarly for the
+container aggregates. End of story.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, March 2, 2018  7:10 PM
+
+>> Not sure what you mean by "them" in "can't use them."  Did
+>> you mean vectors?  The proposal does support them, but with a
+>> precondition that the low bound matches Index_Type'First.
+>
+> "them" = iterated-element-association.
+
+Oh!  I wouldn't have guessed...
+
+> I've mostly been thinking about how they fit into the array aggregate rules.
+> Once that is figured out, then one can use similar rules for container
+> aggregates. Starting with the containers is ass-backwards -- that's a blank
+> slate, whereas with the arrays they have to be fit into existing wording.
+
+Perhaps, but I don't see anyone screaming for more kinds of array aggregates,
+whereas aggregates for containers seems like an obvious hole in the current
+standard.
+
+> As I've previously noted, I do not want incentives to use one kind of type
+> over the other (in either direction), so anything available in the
+> containers also has to be available in array aggregates.
+
+Yeah, but vectors and arrays have one fundamental difference -- vectors are
+extensible, but of course imply dynamic or bounded allocation.  So there is
+already a pretty strong incentive to use the "right" one, and a few extra
+syntactic alternatives for the aggregates of one over the other seems OK
+given that they have this fundamental difference in functionality.
+
+> Aside: The first paragraph of the Legality Rules just provides definitions.
+> Shouldn't that be in Static Semantics?
+
+We have allowed definitions to be almost anywhere as far as I know, and
+certainly we allow them in legality rules.
+
+> Unless you plan to define a
+> whole new set of bounds rules -- and even that would have to limit
+> them to one iterator per aggregate (I sure hope we're not planning to
+> dump the "one dynamic choice" rule only in this weird case). That
+> doesn't seem to be the way you wanted to go -- but perhaps you've
+> decided to abandon iterators in aggregates except in the map case???
+
+Did you look at the proposal?  If so, please clarify your
+concern.  If not, please take a look at the proposal for how
+Vectors would be supported, and if you have comments on that,
+let me know.
+
+> The idea that a named aggregate uses Add_Positional is bizarre. It works
+> here because of the blank-slate issue, but it will not work with arrays.
+
+I don't see the issue.  As pointed out, arrays and vectors are not the same
+thing, fundamentally because you can add elements to a vector, and you cannot
+add elements to an array.  I think you are over-constraining the solution by
+requiring them to have identical capabilities.  I agree they should be as
+similar as possible, but we should not have to sacrifice the functionality of
+one just because non-extensible arrays can't handle them.
+
+> Well, actually it doesn't work that well here. You now have the possibility
+> of mixed keyed and unkeyed choices (because you are treating an iterator as
+> named even though it doesn't provide any). For instance:
+>
+>   A_Map := ("Tuck" => True, "Randy" => False, for E of Some_Bits => E);
+>
+> Assuming that both Add_Named and Add_Positional are supported, this
+> "aggregate" would be implemented with a mix of "named" and "positional"
+> inserts - that seems like madness. (A type supporting both could make sense
+> for a keyed set, for instance.)
+
+That was not my intent.  The rules should probably disallow this mixing.  In
+fact, now that we have New_Indexed/Assign_Indexed, we could probably disallow
+having both Add_Named and Add_Positional for the same type.   Set-like types
+would use Add_Positional, and Map-like types would use Add_Named, and
+Vector-like types could have both Add_Positional and Assign_Indexed.  I can't
+imagine now a type that would require having both Add_Named and Add_Positional.
+Even a "keyed set" doesn't gain anything from using named notation, and in fact
+giving names just creates trouble since you would require that the name matches
+the key embedded in the value.  So I would say we should disallow that
+combination for now.  If someone eventually comes up with an important use for
+it, we could add it back.
+
+> It's also bizarre (and violates my rule above), that you can write:
+
+Let's not talk about "rules" yet...
+
+>   A_Map := (for E of Some_Bits => E, for E of Some_Other_Bits => E);
+>
+> for a map, but it's illegal for an array or vector.
+
+Not sure why you are saying the above is illegal for a vector.  Add_Positional
+works for a vector.
+
+> And it's bizarre that you can write:
+>
+>   A_List := (for I in 1..1 => True, for I in 1..1 => False,
+>              for E of Some_Bits => E);
+>
+> but you're not allowed to write:
+>
+>   A_List := (True, False, for E of Some_Bits => E);
+
+This is mixing positional and named, which is not something we have allowed
+in the past.  I can understand your interest in this, but not supporting it
+is not "bizarre" in my view.
+
+> (since lists are only positional, and the only named choices that a
+> positional type can write are iterators). If we adopted these rules as-is, I
+> predict you'll see the above pretty often.
+
+Another option is to just rely on concatenation:
+
+  A_List := (True, False) & (for E of Some_Bits => E);
+
+which doesn't seem so bad.
+
+Clearly some array-like containers might allow
+arbitrary bounds, and others, such as Vector, would require
+the same low bound for all objects of a given type.  I
+presumed a precondition could be used to enforce the
+vector-like requirement of a fixed low bound.
+
+> I've said repeatedly that I would want to see how these iterators are
+> integrated into the array containers before worrying about anything else.
+
+I think you are beginning to get a bit autocratic here.  I understand your
+desire to keep nearly equivalent functionality, but you are starting to sounds
+like these are uncompromisable demands.   Let's keep this to "in my view..."
+or something.  The veto-like terminology gets old...
+
+> That makes the most sense as positional, at the very least in terms of how
+> the bounds are determined, the legality rules on the indexes are checked,
+> and the like. If you try to add them to named aggregates, you'll need to
+> make a special case for every rule that applies to such an aggregate
+> ("unless it contains an iterator, in which case the bounds are completely
+> different").
+>
+> If they end up being part of positional aggregates for arrays (definitely
+> the easiest way to deal with them), then they ought to be handled similarly
+> for the container aggregates. End of story.
+
+Again, there are multiple views here.  I am happy to be part of a search for
+solutions that make us all happy, but lets not start making threats.  It
+really doesn't help.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Saturday, March 3, 2018  11:06 PM
+
+>> I've mostly been thinking about how they fit into the array aggregate rules.
+>> Once that is figured out, then one can use similar rules for
+>> container aggregates. Starting with the containers is ass-backwards
+>> -- that's a blank
+>> slate, whereas with the arrays they have to be fit into existing wording.
+
+> Perhaps, but I don't see anyone screaming for more kinds of array aggregates,
+> whereas aggregates for containers seems like an obvious hole in the current
+> standard.
+
+Doesn't seem that "obvious" to me; the best feature of aggregates is the
+completeness checks but those don't make any sense for containers. Thus,
+container aggregates seem logical but hardly critical.
+
+>> As I've previously noted, I do not want incentives to use one kind of type
+>> over the other (in either direction), so anything available in the
+>> containers also has to be available in array aggregates.
+
+> Yeah, but vectors and arrays have one fundamental difference -- vectors are
+> extensible, but of course imply dynamic or bounded allocation.  So there is
+> already a pretty strong incentive to use the "right" one, and a few
+> extra syntactic alternatives for the aggregates of one over the other
+> seems OK given that they have this fundamental difference in functionality.
+
+???  Extensibility doesn't have much to do with aggregates, because they are
+an all-at-once construction of an object. And arrays can be unconstrained, so
+aggregates with variable lengths make sense for both. Thus, they seem like two
+views of the same thing to me.
+
+>> Aside: The first paragraph of the Legality Rules just provides definitions.
+>> Shouldn't that be in Static Semantics?
+
+> We have allowed definitions to be almost anywhere as far as I know,
+> and certainly we allow them in legality rules.
+
+That paragraph seems out of place to me, as it has nothing to do with
+legality. (And not much to do with the actual legality rules, either.) When
+I wrote that, I thought there was a Static Semantics section, and I thought
+the definition fit better there. But I can't find that section now, so I
+apparently imagined that.
+
+...
+>> The idea that a named aggregate uses Add_Positional is bizarre. It
+>> works here because of the blank-slate issue, but it will not work with arrays.
+
+> I don't see the issue.
+
+Obviously. :-)
+
+> As pointed out, arrays and vectors are not the same thing,
+> fundamentally because you can add elements to a vector, and you cannot
+> add elements to an array.
+
+Which has precisely nothing to do with a construct for constructing an object
+from scratch.
+
+> I think you are over-constraining the solution by requiring them to
+> have identical capabilities.  I agree they should be as similar as
+> possible, but we should not have to sacrifice the functionality of one
+> just because non-extensible arrays can't handle them.
+
+Who said anything about "sacrificing" anything? All I've said is that I want
+the rules to be essentially the same for both. That doesn't require any
+functionality to be dropped.
+
+...
+>> It's also bizarre (and violates my rule above), that you can write:
+>
+>	Let's not talk about "rules" yet...
+
+Substitute "principle" then. Sheesh.
+
+>>
+>>	   A_Map := (for E of Some_Bits => E, for E of Some_Other_Bits =>
+E);
+>>
+>>	for a map, but it's illegal for an array or vector.
+>
+> Not sure why you are saying the above is illegal for a vector.
+> Add_Positional works for a vector.
+
+You have a Legality Rule that says that an iterator can only occur once for
+a indexed aggregate type. That seems to prevent the above. (If it doesn't,
+I'd object even louder, because the form of an iterator certainly shouldn't
+change the legal uses.)
+
+
+>>And it's bizarre that you can write:
+>>
+>>   A_List := (for I in 1..1 => True, for I in 1..1 => False,
+>>              for E of Some_Bits => E);
+>>
+>>		but you're not allowed to write:
+>>
+>>   A_List := (True, False, for E of Some_Bits => E);
+>
+>This is mixing positional and named, which is not something we have
+>allowed in the past.  I can understand your interest in this, but not
+>supporting it is not "bizarre" in my view.
+
+You've missed my point: people WILL write the former because they aren't
+allowed to write the latter. That's what's "bizarre". I'd be happy to make
+both of them illegal -- it just doesn't make sense to allow a really complex
+way to write something and not allow a much simpler way to write the same
+thing.
+
+>>(since lists are only positional, and the only named choices that a
+>>positional type can write are iterators). If we adopted these rules
+>>as-is, I >>predict you'll see the above pretty often.
+
+>Another option is to just rely on concatenation:
+>
+>	  A_List := (True, False) & (for E of Some_Bits => E);
+>
+>	which doesn't seem so bad.
+
+...except the lists don't have "&". And even if they did have "&", the above
+requires creating three objects and copying all of the contents of two of
+them. That's a lot of unnecessary overhead.
+
+...
+>>	I've said repeatedly that I would want to see how these iterators are
+>>	integrated into the array containers before worrying about anything else.
+>
+>	I think you are beginning to get a bit autocratic here.  I understand your
+> desire to keep nearly equivalent functionality, but you are starting to sounds
+> like these are uncompromisable demands.   Let's keep this to "in my view..." or
+> something.  The veto-like terminology gets old...
+
+Huh? I said "I would want", which is a fact. You can ignore that "want" if you
+like, but I don't view this as something that I am likely to compromise much
+on.
+
+Moreover, it's possible that having worked out the array rules, we'll find
+that it makes more sense to structure the aggregates as you have proposed. I
+I just want to have that (array rules) done first, before we finalize too much
+of these container rules. They make the organization of the container rules be
+more sensible.
+
+>>That makes the most sense as positional, at the very least in terms of
+>>how the bounds are determined, the legality rules on the indexes are
+>>checked, and the like. If you try to add them to named aggregates,
+>>you'll need to make a special case for every rule that applies to such
+>>an aggregate ("unless it contains an iterator, in which case the
+>>bounds are completely different").
+>>
+>>If they end up being part of positional aggregates for arrays
+>>(definitely the easiest way to deal with them), then they ought to be
+>>handled
+similarly
+>>for the container aggregates. End of story.
+>
+>Again, there are multiple views here.  I am happy to be part of a search for
+>solutions that make us all happy, but lets not start making threats.
+>It really doesn't help.
+
+I don't see any threat here, certainly wasn't making one. I have just said
+repeatedly that I want to see how the new iterators fit into array aggregates
+(which already have a pile of rules) before finalizing the container rules
+(which are more of a blank page). Otherwise, we're likely to end up with
+something that is more different than necessary.
+
+I agree that having the iterators be "positional" is somewhat weird -- it
+was my complaint with your first draft of this AI. But more thought on the
+subject shows that that is the only realistic possibility (which you
+implicitly agree with by having them use the Add_Positional routine). I also
+realized that we already have "others => expr" in the array positional cases,
+so it hardly would be unusual to have more such cases.
+
+Array aggregates are syntactically divided into positional and named (indexed
+for the containers) cases, and the rules are almost all different for the two
+cases. I find the mixing in your current container proposal (where the syntax
+is divided, but then the rules end up being blended together in an almost
+arbitrary manner) uncomfortable. On top of which, it prevents reasonable
+container aggregates unless someone writes them with phony iterators. How does
+that help?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, March 9, 2018  11:31 PM
+
+A couple of extra thoughts on this, noted when filing these messages tonight:
+
+> Tucker writes:
+>
+> >> I've mostly been thinking about how they fit into the array
+> >> aggregate rules. Once that is figured out, then one can use similar
+> >> rules for container aggregates. Starting with the containers is
+> >> ass-backwards
+> >> -- that's a blank slate, whereas with the arrays they have to be
+> >> fit into existing wording.
+>
+> > Perhaps, but I don't see anyone screaming for more kinds of array
+> > aggregates, whereas aggregates for containers seems like an obvious
+> > hole in the current standard.
+
+I responded:
+> Doesn't seem that "obvious" to me; the best feature of aggregates is
+> the completeness checks but those don't make any sense for containers.
+> Thus, container aggregates seem logical but hardly critical.
+
+I should point out that we're really discussing the iterator cases here. Most
+of the "problem" to be solved by container aggregates are solved by simple
+positional or mapped aggregates:
+    A_List := (A, B, C);
+    A_Map := ("Randy" => A, "Tucker" => B);
+
+I have no problem with the portion of the solution involving them (it looks
+fine to me).
+
+OTOH, adding container iterators into this mix is not so obvious, neither in
+terms of the need or in terms of how they fit into the existing kinds of
+aggregates or even how they fit into the proposal itself.
+
+Tucker has been ascribing nearly magical properties to various uses of these
+iterators, in ways that tend to trigger my BS detector. That's tempered by the
+fact that Tucker usually isn't the sort to rave on crazily. Still, anyone can
+get over-enthusiastic about something (that's probably how I got here in the
+first place ;-).
+
+*IF* it was up to me solely, I would treat the solution to the obvious
+container aggregate problem separate from the question of adding containers
+iterators to *any* aggregates. And, the AI for that latter case, I would add
+the iterators to both array and container aggregates at the same time. (If
+it's good for the one, it has to be good for the other -- they're different
+views of the same thing, the only difference being that arrays are built in.)
+I think any other path for additional iterators to be folly for many reasons,
+the most obvious being that creating an array from a container should be no
+harder than creating a container from an array.
+
+This shouldn't be considered a demand - if I'm the only one that feels this
+way, I can take a hint...
+
+Aside: I like how Tucker snuck in a notation for an empty container aggregate
+into his container AI, despite already having another AI open for that, and
+despite that other AI not getting much traction. I'm going to resist saying
+more...
+
+...
+
+> > Yeah, but vectors and arrays have one fundamental difference --
+> > vectors are extensible, but of course imply dynamic or bounded
+> > allocation.  So there is already a pretty strong incentive to use
+> > the "right" one, and a few extra syntactic alternatives for the
+> > aggregates of one over the other seems OK given that they have this
+> > fundamental difference in functionality.
+
+I said:
+> ???  Extensibility doesn't have much to do with aggregates, because
+> they are an all-at-once construction of an object.
+> And arrays can be unconstrained, so aggregates with variable lengths
+> make sense for both. Thus, they seem like two views of the same thing
+> to me.
+
+To expand a bit, it's clear that the underlying implementation of containers
+aggregates use operations to add the elements to the container one at a time.
+That's where the extensibility comes into play. However, the programmer model
+for an aggregate is that it is built all at once -- one hopefully is not
+looking under the hood here to see how it *really* is implemented. Since the
+"thought" model for an aggregate is something built as a single object all at
+once, extensibility doesn't come into play.
+
+It would come into play if you wrote a normal for loop statement to fill the
+container:
+
+       for E of Some_Array loop
+           Append (New_Container, E);
+       end loop;
+
+but an aggregate iterator is logically done all at once in an arbitrary order;
+there's no implied order involved. (Indeed, it would be a candidate for as-if
+parallel operation if such a thing actually made sense on typical hardware.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, March 10, 2018  11:31 PM
+
+> ...
+> Aside: I like how Tucker snuck in a notation for an empty container
+> aggregate into his container AI, despite already having another AI
+> open for that, and despite that other AI not getting much traction.
+> I'm going to resist saying more...
+
+The more I worked on the "(null T)" idea for an empty aggregate of type T, the
+less I liked it.  Since the container aggregate required the specification of
+an "Empty" operation, it made sense to me to include a notation for an empty
+aggregate as part of the container aggregate AI, and make it something that
+didn't require the full name of the type to be buried in the aggregate.  We
+generally don't allow you to look inside an aggregate until you know exactly
+what type it is, so it seemed particularly silly to repeat the full name of
+the type inside an empty aggregate.  Once we leave out the full name of the
+type from the "empty" aggregate, the notation that kept seeming the most
+obvious to me for things like "empty set" and "empty map" was "(<>)".
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, March 10, 2018  9:58 AM
+
+> ...
+> I should point out that we're really discussing the iterator cases here.
+> Most of the "problem" to be solved by container aggregates are solved
+> by simple positional or mapped aggregates:
+>    A_List := (A, B, C);
+>    A_Map := ("Randy" => A, "Tucker" => B);
+>
+> I have no problem with the portion of the solution involving them (it
+> looks fine to me).
+>
+> OTOH, adding container iterators into this mix is not so obvious,
+> neither in terms of the need or in terms of how they fit into the
+> existing kinds of aggregates or even how they fit into the proposal itself. ...
+
+We added iterators to array aggregates after 20 years, and they were sorely
+missed.  The point is that you often want to create an aggregate where the
+components are systematically a function of the position, or something else
+that is varying.  Turning your logic around, it would be weird to allow the
+following for an array aggregate but not for a vector aggregate:
+
+   (for I in 1..N => I**2)
+
+The *only* controversy seems to be whether we should require supporting
+container iterators in array aggregates, and that seems to be only a
+controversy for you.  Everyone else seems to see it as clear that we should
+focus on allowing container iterators in container aggregates, since a
+frequent use (in my experience, as well as the experience in using similar
+constructs in Python and other languages), is that you want to create a new
+container that is an element-wise function of some other container.  E.g.,
+given a set, you want to create a new set that contains, say, the square of
+each element, or the mapping of each element to some other type, ...
+
+There is less need to construct an array as an element-wise function of a
+container in my experience, and the added expense of having to pre-allocate
+the array makes this less attractive from an implementation point of view.
+I am happy to add this feature, but it feels like a separate issue, with
+more complex implementation requirements, and I wouldn't want to "sink" the
+container aggregate idea overall just because supporting an array as an
+element-wise function of a container requires a more complex implementation.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Saturday, March 10, 2018  7:37 PM
+
+...
+> > OTOH, adding container iterators into this mix is not so obvious,
+> > neither in terms of the need or in terms of how they fit into the
+> > existing kinds of aggregates or even how they fit into the
+> proposal itself. ...
+>
+> We added iterators to array aggregates after 20 years, and they were
+> sorely missed.
+
+Not by me. I think there were a handful of cases in my 40 years of programming
+where they would have helped. Definitely a non-zero need, but hardly something
+critical.
+
+... The point is that you often want to
+> create an aggregate where the components are systematically a function
+> of the position, or something else that is varying.
+> Turning your logic around, it would be weird to allow the following
+> for an array aggregate but not for a vector aggregate:
+>
+>    (for I in 1..N => I**2)
+
+Wouldn't mind this at all, so long as it follows array iterator rules -- that
+is, it calls Add_Indexed in your current draft.
+
+...
+> The *only* controversy seems to be whether we should require
+> supporting container iterators in array aggregates, and that seems to
+> be only a controversy for you.  Everyone else seems to see it as clear
+> ...
+
+That is clearly your imagination; we've never discussed this topic at a
+meeting so there is no possible way to know what "everybody else" is
+thinking. My recollection was that this was introduced at a meeting as "what
+we should do" without any real opportunity to digest it ahead of time.
+
+...
+> There is less need to construct an array as an element-wise function
+> of a container in my experience,
+
+How do you know this? We've never had such iterators in Ada, and other
+languages that have such iterators treat arrays similarly to all of the
+other containers -- so how could you tell the difference? An array is just a
+container that is built-in for historical reasons, treating it differently is
+madness.
+
+---
+
+In any case, if "everybody else" agrees with you, then you should clearly
+ignore me. Which is essentially what you've been doing on this topic, so it
+isn't worth any more of my time in this venue. (We can fight it out at
+whatever meeting this AI gets discussed.)
+
+To summarize, I can't support the current proposal for a myriad of reasons:
+
+(1) The proposal is unnecessarily different than array aggregates: The
+    iterators allowed and the interpretation is different for the arrays and
+    the containers, ranges aren't allowed as indexed choices for no known
+    reason, nor is <> allowed for the named forms (why a default initialized
+    component is valuable for an array and not for a container escapes me).
+
+(2) <> in an aggregate means "default initialize", and to use it to represent
+    an empty container is a nasty collision of meanings in essentially the
+    same construct. (Ideally, "<>" would mean default-initialization
+    everywhere, but that was a bridge-too-far in the past...I don't want to
+    prevent such a usage.)
+
+(3) There's a separate AI for empty aggregates, and there is no good reason to
+    put that into this one -- Empty_List is a fine way to get an empty list
+    container. (Not to mention that writing such containers explicitly isn't
+    going to happen very often in any case.) Besides, there is no sane way (not
+    even a function) to write a 1-element list (as a positional-only aggregate,
+    the only choice in the current AI is a phony iterator:
+           My_List := (1); -- Not an aggregate.
+           My_List := (for I in 1..1 => 1); -- OK, but insane.)
+    So there is no real "consistency" argument for the need for empty
+    aggregates.
+
+(4) The AI implements "named" aggregates with the "positional"
+    implementation (the Add_Positional subprogram). This weird mixing of
+    concepts is very uncomfortable.
+
+(5) The AI as written allows elements implemented by positional and named
+    routines in the same aggregate. (You did promise to fix this.)
+
+I'm not against this concept per-se, but I'm definitely against this
+implementation of the concept.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, March 11, 2018  10:47 AM
+
+> ...
+> I'm not against this concept per-se, but I'm definitely against this
+> implementation of the concept.
+
+I'll take another shot at this AI, and hopefully can reach some kind of middle
+ground here.
+
+I would point out that in many languages, (non-extensible) arrays and
+(extensible) vectors are two different things, and treated quite differently.
+But I'll try to make the aggregates more consistent between them in the next
+version of the AI.
+
+****************************************************************
+
+From: Jeff Cousins
+Sent: Monday, March 12, 2018  10:23 AM
+
+>> We added iterators to array aggregates after 20 years, and
+>> they were sorely missed.
+
+>Not by me. I think there were a handful of cases in my 40 years of
+> programming where they would have helped.
+
+At least I agree with Tucker on this bit, I would have used almost daily.
+
+>> The *only* controversy seems to be whether we should require
+>> supporting container iterators in array aggregates, and that
+>> seems to be only a controversy for you.  Everyone else seems
+>> to see it as clear ...
+
+>That is clearly your imagination; we've never discussed this topic at a
+>meeting so there is no possible way to know what "everybody else" is
+>thinking.
+
+The only recent-ish messages seem to have been from Randy and Tucker.
+Personally Iím confused as to what exactly is being proposed here Ė and I
+suspect that itís the same for some pf the other members, hence why theyíre
+not commenting Ė and would have to abstain if it came to a vote.
+
+****************************************************************
+
+From: Edmond Sconberg
+Sent: Monday, March 12, 2018  11:15 AM
+
+I share Jeff's sense of confusion,  I am all in favor of the proposed
+container aggregates and the new attributes for indexed, named, and keyed
+insertions.  I donít know what the exact proposal is for new array aggregates.
+I agree that it is worthwhile generalizing the use of container iterators
+wherever a loop is implied. (the issue of the size of an array aggregate built
+with an iteration over a container is an implementation question, the
+point is that the notation is useful). If the context is an array type, and S
+is a hashed set,  I can make sense of  (for X of S => F (X)),  but given
+that the iteration over S produces values in some unspecified order Iíve
+created an array with elements in unpredictable order. Not sure that this
+is particularly useful. If we really need to produce indexable sequences
+from other containers, vectors may be all we need.
+
+Finally, I find  (<>) perfectly acceptable as a notation for an empty
+container!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 12, 2018  2:48 PM
+
+> I share Jeff's sense of confusion,  I am all in favor of the proposed
+> container aggregates and the new attributes for indexed, named, and keyed
+> insertions.  I donít know what the exact proposal is for new array
+> aggregates.
+
+I don't know what the exact proposal is either, because there hasn't been
+one. Which is the core of my objection - the array case is harder to define
+since it has to fit into the existing rules. So I'd like to see that before
+getting too far into the containers aggregate proposal - it might make sense
+to make the rules similar for the two cases.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, March 12, 2018  5:13 PM
+
+A new version is forthcoming...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, March 13, 2018  5:23 PM
+
+OK, here is another shot at container aggregates, including a section on
+generalizing array aggregates. [This is version /06 of the AI - ED.]  I still
+didn't allow having a positional container aggregate with an iterator part at
+the end.  Still feels weird to me, but could be added later if the ARG as a
+whole really wants it.
+
+Other major changes -- now call the operation "Add_Unnamed" rather than
+"Add_Positional," since it is used in both positional and named aggregates.
+Don't allow both Add_Unnamed and Add_Named for the same type.  Allow "<>" in
+"indexed" aggregates.  Allow discrete ranges in indexed aggregates.  Removed
+a few of the overly complex examples.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent