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

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

--- ai12s/ai12-0212-1.txt	2017/08/08 03:32:37	1.5
+++ ai12s/ai12-0212-1.txt	2018/01/25 05:38:34	1.6
@@ -1,4 +1,4 @@
-!standard 4.3.5(0)                                  17-06-10  AI12-0212-1/01
+!standard 4.3.5(0)                                  18-01-24  AI12-0212-1/02
 !class Amendment 16-12-27
 !status work item 17-06-10
 !status received 16-06-12
@@ -7,7 +7,7 @@
 !subject Container aggregates
 !summary
 
-Add syntax to construct container instances.
+Add aggregate syntax to construct container instances.
 
 !problem
 
@@ -21,13 +21,15 @@
      separate function
 
 An obvious approach would be to add functions that initialise a container from
-an aggregate of a unconstrained array, for example:
+an aggregate of an unconstrained array, for example:
 
    X : Example.Set := Example.From_Array ((1, 2, 3));
 
-However there are a number of drawbacks: the syntax is ugly (double brackets),
-it would not allow comprehensions (only displays), and it would only work for
-array-like containers and not maps.
+However there are a number of drawbacks: the syntax is ugly (double
+brackets), it would not allow comprehensions (i.e. containers defined by
+a nested iterator) (only displays -- i.e. an explicit list of
+components), and it would only work for array-like containers and not
+maps.
 
 There are three places where container aggregates may be useful: in ordinary
 code (but here we can just do what we do right now), for the definition of
@@ -40,14 +42,15 @@
 
 This proposal works for most of the standard containers (Vectors,
 Doubly_Linked_Lists, Hashed_Sets, Ordered_Sets, Hashed_Maps and Ordered_Maps
-including their bounded and indefinite versions). Multiway_Trees are are not
+including their bounded and indefinite versions). Multiway_Trees are not
 supported by this proposal.
 
 The syntax is highly inspired by Python (please do not let that put you off), it
 just is more Ada-like than comprehension in, say, Haskell.
 
-In the most simple form (called a display) we just give the elements to add in a
-form very similar to a simple array aggregate:
+In the most simple form (called a positional container aggregate) we
+just give the elements to add in a form very similar to a simple array
+aggregate:
 
    X : My_Set := (1, 2, 3);
 
@@ -58,12 +61,13 @@
    Include (X, 3);
 
 The function or constant "Empty_Set" is one of the two things you specify in the
-Comprehension aspect, the procedure "Include" is the other.
+Aggregate aspect, the procedure "Include" is the other.
 
-Displays are good for defining simple container instances, but often, you might
-want to derive one container from another (a concept that is called
-comprehension). This is vaguely related to a delta aggregate, but neither
-construct can easily emulate the other.
+Positional container aggregates are good for defining simple container
+instances, but often, you might want to derive one container from
+another (a concept that is called comprehension). This is vaguely
+related to a delta aggregate, but neither construct can easily emulate
+the other.
 
 Here we loop over one container and apply some function to each item. Thy
 proposed syntax steals from existing loop and quantifier syntax:
@@ -78,7 +82,7 @@
 
 We may also wish to filter the items:
 
-   Z : My_Set := (for Item of X if Item > 1 => Item - 1);
+   Z : My_Set := (for Item of X when Item > 1 => Item - 1);
 
    --  Equivalent to:
    Z : My_Set := Empty_Set;
@@ -88,14 +92,11 @@
       end if;
    end loop;
 
-Instead of "if" we could use "|" to mimic common mathematical notation, but it
-is probaby not a good idea to introduce the vertical bar into Ada at this point?
-
-Finally, it is also a common pattern to aggregate multiple containers into one.
+Finally, it is also a common pattern to combine multiple containers into one.
 Two approaches are supported. This is the nested (or "product") one:
 
    W : My_Set := (for A of X =>
-                    for B of X => A * B);
+                    for B of X => A * B);  --  TBD: Not currently in this AI
 
    --  Equivalent to:
    W : My_Set := Empty_Set;
@@ -105,7 +106,7 @@
       end loop;
    end loop;
 
-And this is the sequential (or "list") one:
+This is the sequential (or "list") one:
 
    V : My_Set := (for A of X => A,
                   for A of X => -A);
@@ -119,6 +120,20 @@
       Include (V, -A);
    end loop;
 
+This is the concurrent one (TBD --  not in this AI yet):
+
+   V : My_Set := (for (A of X; I in 1..Max) => (A, I));
+   -- TBD: Not currently in this AI yet
+   
+   --  Equivalent to:
+   V : My_Set := Empty_Set;
+   for (A of X; I in 1..Max) loop
+      Include (V, (A, I));
+   end loop;
+   
+   --  where the parenthesized iterators run concurrently, with the iteration
+   --  stopping when either runs out of elements.  
+   
 The new contract on the set container would be:
 
    type Set is tagged private
@@ -127,133 +142,218 @@
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
            --  this is new
-           Comprehension     => (Empty     => Empty_Set,
-                                 Inclusion => Include);
+           Aggregate         => (Empty => Empty_Set,
+                                 Add_Positional => Include);
 
-For containers where the Inclusion procedure has 2 parameters, we propose syntax
-using =>:
+For containers such as maps, an Add_Named component of the Aggregate
+aspect would be specified, to enable a usage such as:
 
    M : My_Map := (42 => "foo",
                   88 => "bar");
 
 So, to summarise:
-* Now aspect on private types specifying an empty default and a procedure
-  with one (element) or two (key and value) parameters
+* New aspect on types specifying an empty default, plus either an 
+  Add_Positional or an Add_Named procedure (or both).
 * Extend aggregate syntax to trigger these
 
 Related changes:
 
-This AI will have some interesting interplay with let expressions and
+This AI will have some interesting interplay with declare expressions and
 generators.
 
-This AI will (trivially) conflict with AI12-0127-1 (partial aggregates) as both
-add a new section to 4.3 and modify the syntax for 4.3.
-
 !wording
 
 4.3 Aggregates (Syntax)
 
-Change:
+Change paragraph 2/5:
 
    aggregate ::= record_aggregate | extension_aggregate | array_aggregate
+               | delta_aggregate
 
 To:
-
-   aggregate ::= record_aggregate | extension_aggregate | array_aggregate |
-                 display_aggregate | comprehension_aggregate
-
-Add new section: 4.3.4 Comprehension and Display Aggregates
 
+   aggregate ::= record_aggregate | extension_aggregate | array_aggregate
+               | delta_aggregate | container_aggregate
+               
+Modify paragraph 3/5:
+
+  The expected type for a delta_aggregate shall be a single array type,
+  or a single descendant of a record type or of a record extension. The
+  expected type for any other aggregate shall be a single array type,
+  record type, [or ]record extension{, or other composite type with the
+  Aggregate aspect specified}.
+
+Add new section: 4.3.5 Container Aggregates
+
+In a container_aggregate, values are specified for elements of a
+container; for a positional_container_aggregate, the elements are given
+sequentially; for a named_container_aggregate, the elements are
+specified by a sequence of key/value pairs, or using an iterator.
+The Aggregate aspect of the type of the aggregate determines how the 
+elements are combined to form the container.
+   
+Given a private type or private extension T, the following type-related
+operational aspect may be specified:
+  AARM Reason: We require the type to be a partial view so it is
+  clear that the aggregate should not be interpreted as some other
+  kind of aggregate, since syntactically it is indistinguishable.
+
+  Aggregate
+    This aspect is of the form: 
+    
+      (Empty => name[,
+       Add_Positional => /procedure_/name][,
+       Add_Named => /procedure_/name])
+       
+    Either Add_Positional, Add_Named, or both shall be specified.
+       
+Name Resolution Rules
+
+    The name specified for Empty shall denote a constant of type T,
+    or denote a function with a result type of T that has no parameters,
+    or that has one IN parameter of type Integer with a default expression.
+      AARM Reason: In the function case, the parameter, if present, 
+      may be used to specify an initial size for the container, in
+      anticipation of adding elements to it.  For a positional
+      aggregate, or a named aggregate that doesn't use an iterator, it
+      will be initialized with the number of elements.  For a named
+      aggregate that uses an iterator, the implementation is permitted
+      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
+    have 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.
+    
+    The /procedure_/name specified for Add_Named, if any, shall have
+    three parameters, the first an IN OUT parameter of type T,
+    the second an IN parameter of a nonlimited type, that is called the
+    /key type/ of the container, and the third, an IN parameter of a
+    nonlimited type that is called the /element type/ of T.
+    
+    If both Add_Positional and Add_Named are specified, the final 
+    parameters shall be of the same type -- the element type of T.
+    
+    
 Syntax
-
-   display_aggregate ::= ( unary_display | binary_display )
 
-   unary_display ::= expression {, expression}
+   container_aggregate ::=
+     positional_container_aggregate | named_container_aggregate
+     
+   positional_container_aggregate ::= (expression, expression {, expression)
+   
+   named_container_aggregate ::= (container_element_association_list)
+   
+   container_element_association_list ::=
+     container_element_association {, container_element_association}
+     
+   container_element_association ::=
+     key_expression_list => expression
+   | iterated_element_association
+   
+   key_expression_list ::= /key_/expression {| /key_/expression}
+   
+   iterated_element_association ::=
+      for loop_parameter_specification[, /key_/expression] => expression
+    | for iterator_specification[, /key_/expression] => expression
+
+Name Resolution Rules
+
+The expected type for a container_aggregate shall be a type for which
+the Aggregate aspect has been specified.  The expected type for each
+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.  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 procedure.  The expected type
+for each such /key_/expression is the key type of the expected type.
 
-   binary_display ::= binary_association {, binary_association}
-
-   binary_association ::= expression => expression
-
-
-   comprehension_aggregate ::= ( product_comprehension {,
-                                 product_comprehension} )
-
-   product_comprehension ::=
-     item_selector {=> item_selector} => comprehension_item
-
-   item_selector ::= for_iteration_scheme [ if expression ]
-
-   comprehension_item ::= expression | binary_association
-
 Legality Rules
-
-The comprehension aspect can be specified on any type.
-
-The underlying type of a comprehension aggregate or display aggregate must bear
-a Comprehension aspect.
 
-An aggregate for a type with a unary inclusion procedure must use a
-unary_display or expression comprehension_items. An aggregate for a type with a
-binary inclusion procedure must use a binary_display or binary_association
-comprehension_items.
+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, then the type of the loop parameter
+of the iterated_element_association shall be the same as the key type of T.
+  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.
 
-STEVE HELP ME
-- I think the expected type of the aggregate needs to be from the outside
-  context, not the aggregate itself
-- wording to constrain the expected type for all expressions
-
-Static Semantics
-
-STEVE HELP ME THIS IS PROBABLY REALLY WRONG AND PROBABLY NEEDS TO BE IN A
-DIFFERENT PLACE
-
-A Comprehension aspect aspect_mark is "Comprehension", and its aspect_definition
-is a record aggregate with exactly two selectors: "Empty" and "Inclusion".
-
-The expression for choice "Empty" can the name of a constant or a parameterless
-function, and must match the type for which the aspect is defined.
-
-The expression for choice "Inclusion" must be the name of a procedure with two
-(for the unary case) or three parameters (for the binary case). The first
-parameter of the inclusion procedure must be of mode in out and match the type
-for which the aspect is defined.
-
-STEVE HELP ME WITH MAGIC TO MAKE DEFAULT PARAMETERS WORK HERE, NEEDED FOR
-VECTORS FOR EXAMPLE...
-
 Dynamic Semantics
+
+The evaluation of a container_aggregate starts by creating an anonymous
+object A of the expected type T initialized by assignment from the Empty
+constant, or from a call on the Empty function specified in the Aggregate
+aspect.  In the case of an Empty function, the parameter, if any, is
+initialized as follows:
+   * for a positional_container_aggregate, the number of expressions;
+   * for a named_container_aggregate without an iterated_element_association,
+     the number of container_element_associations;
+   * otherwise, to an implementation-defined value.
+
+The evaluation then proceeds as follows:
+  * for a positional_container_aggregate, each expression is evaluated
+    in any 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 in the order of the expressions;
+  * for a named_container_aggregate for a type with an Add_Named procedure
+    in its Aggregate aspect, the container_element_associations are evaluated
+    in any order:
+     * for a container_element_association with a key_expression_list,
+       for each /key_/expression of the list in any order, the 
+       /key_/expression is evaluated as is the expression of the
+       container_element_association (in any 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 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 iteration
+       the Add_Named procedure is invoked with the anonymous object A as
+       the first parameter, the result of evaluating the expression
+       as the third parameter, and:
+          * if there is a /key_/expression, the result of evaluating
+            the /key_/expression as the second parameter;
+          * otherwise, with the loop parameter as the second parameter;
+   * for a named_container_aggregate for a type without an Add_Named
+     procedure in its Aggregate aspect, 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
+         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.
 
-The evaluation of a display_aggregate or comprehension_aggregate starts by
-creating a new object, evaluating the Empty function of the Comprehension aspect
-and assigning its result to the new object.
-
-For a unary_display the unary inclusion procedure is called for each expression
-in order, for a binary_display the binary inclusion procedure is called for each
-pair described by the binary_association.
-
-For a comprehension_aggregate, each product_comprehension is evaluated in order.
-
-STEVE I AM TOTALLY LOST HOW TO WORD THIS, PLEASE MAKE IT LOOP IN THE OBVIOUS WAY
-
-To evaluate a product_comprehension, we iterate over the for_iteration_scheme of
-the first item_selector. If the if expression exists, and evaluates to False, we
-skip to the next item. Each following item_selector is evaluated in a similar
-fashion, and finally the comprehension_item is evaluated and the appropriate
-inclusion procedure is called.
 
 Examples
 
 I KNOW I NEED TO REWORK THESE TO USE EXISTING THINGS IN THE RM
 
-   --  Declares a type with comprehension.
-   type Set_Type is array (0 .. 1000) of Boolean
-     with Comprehension => (Empty     => Empty_Set;
-                            Inclusion => Merge);
-   Empty_Set : constant Set_Type := (others => False);
+   --  Declares a container type.
+   type Set_Type is private
+     with Aggregate => (Empty          => Empty_Set;
+                        Add_Positional => Merge);
+   function Empty_Set return Set_Type;
+
    procedure Merge (S : in out Set_Type; N : Integer)
-   with Pre => N in 0 .. 1000;
+     with Pre => N in 0 .. 1000;
+   
+ private
+ 
+   type Set_Type is array (0 .. 1000) of Boolean
+ 
+   function Empty_Set return Set_Type is (others => False); 
 
-   --  A unary display
+   --  A positional set aggregate
    S := (1, 2);
 
    --  is Equivalent to:
@@ -261,11 +361,10 @@
    S.Include (1);
    S.Include (2);
 
-   --  A binary display
-   M := (12 => "house",
-         14 => "beige");
+   --  A named map aggregate
+   M := (12 => "house", 14 => "beige");
 
-   --  A simple comprehension
+   --  A set aggregate with an iterated_element_association
    S := (for Item in 1 .. 5 => Item * 2)
 
    --  is equivalent to
@@ -274,8 +373,8 @@
       S.Include (Item * 2);
    end loop;
 
-   --  A comprehension with a predicate
-   S := (for Item in 1 .. 100 if Is_Prime (Item) => Item);
+   --  A set aggregate with a filter (separate AI)
+   S := (for Item in 1 .. 100 when Is_Prime (Item) => Item);
 
    --  is equivalent to
    S := Empty_Set;
@@ -285,15 +384,15 @@
       end if;
    end loop;
 
-   --  A simple comprehension consisting out of two product_comprehensions
+   --  A set aggregate consisting out of two iterated_element_associations
    S := (for Item in 1 .. 5 => Item,
          for Item in 1 .. 5 => -Item);
 
    --  Is (mostly, assuming set semantics) equivalent to
-   S := (for Item in -5 .. 5 if Item not in -1 .. 1 => Item);
+   S := (for Item in -5 .. 5 when Item /= 0 => Item);
 
-   --  A product comprehension with more than one item_selector
-   S := (for X in 1 .. 10 => for Y in -1 .. 1 if Y /= 0 => X * Y);
+   --  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;
@@ -306,17 +405,17 @@
    end if;
 
    --  An example that combines all aspects of the grammar
-   S := (for Customer of Cusomter_Database if not Customer.Poor =>
+   S := (for Customer of Customer_Database when not Customer.Poor =>
            Customer.Name,
          for Manager of Managers =>
-            for Staff of Manager.Minions if Staff.Performance >= 3.0 =>
+            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 Cusomter_Database loop
+   for Customer of Customer_Database loop
       if not Customer.Poor =>
-         S.Include (Custoemr.Name);
+         S.Include (Customer.Name);
       end if;
    end loop;
    for Manager of Managers loop
@@ -327,94 +426,77 @@
       end loop;
    end loop;
 
-5.5 Loop Statements (Syntax)
-
-Grammar-refactoring. Change:
-
-   iteration_scheme ::= while condition
-                      | for loop_parameter_specification
-                      | for iterator_specification
-
-To:
-
-   iteration_scheme ::= while condition
-                      | for_iteration_scheme
-
-   for_iteration_scheme ::= for loop_parameter_specification
-                          | for iterator_specification
-
-This allows us to use for_iteration_scheme in the comprehensions directly.
-
 A.18.2 The Generic Package Containers.Vectors
 
-Add the Comprehension aspect to the existing ones on type Vector:
+Add the Aggregate aspect to the existing ones on type Vector:
 
    type Vector is tagged private
       with Constant_Indexing => Constant_Reference,
            Variable_Indexing => Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Comprehension     => (Empty     => Empty_Vector,
-                                 Inclusion => Append);
+           Aggregate         => (Empty          => Empty_Vector,
+                                 Add_Positional => Append);
 
 A.18.3 The Generic Package Containers.Doubly_Linked_Lists
 
-Add the Comprehension aspect to the existing ones on type List:
+Add the Aggregate aspect to the existing ones on type List:
 
    type List is tagged private
       with Constant_Indexing => Constant_Reference,
            Variable_Indexing => Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Comprehension     => (Empty     => Empty_List,
-                                 Inclusion => Append);
+           Aggregate         => (Empty          => Empty_List,
+                                 Add_Positional => Append);
 
 A.18.5 The Generic Package Containers.Hashed_Maps
 
-Add the Comprehension aspect to the existing ones on type Map:
+Add the Aggregate aspect to the existing ones on type Map:
 
    type Map is tagged private
       with Constant_Indexing => Constant_Reference,
            Variable_Indexing => Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Comprehension     => (Empty     => Empty_Map,
-                                 Inclusion => Insert);
+           Aggregate         => (Empty     => Empty_Map,
+                                 Add_Named => Insert);
 
 A.18.6 The Generic Package Containers.Ordered_Maps
 
-Add the Comprehension aspect to the existing ones on type Map:
+Add the Aggregate aspect to the existing ones on type Map:
 
    type Map is tagged private
       with Constant_Indexing => Constant_Reference,
            Variable_Indexing => Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Comprehension     => (Empty     => Empty_Map,
-                                 Inclusion => Insert);
+           Aggregate         => (Empty     => Empty_Map,
+                                 Add_Named => Insert);
 
 A.18.8 The Generic Package Containers.Hashed_Sets
 
-Add the Comprehension aspect to the existing ones on type Set:
+Add the Aggregate aspect to the existing ones on type Set:
 
    type Set is tagged private
       with Constant_Indexing => Constant_Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Comprehension     => (Empty     => Empty_Set,
-                                 Inclusion => Include);
+           Aggregate         => (Empty          => Empty_Set,
+                                 Add_Positional => Include);
 
 A.18.9 The Generic Package Containers.Ordered_Sets
 
-Add the Comprehension aspect to the existing ones on type Set:
+Add the Aggregate aspect to the existing ones on type Set:
 
    type Set is tagged private
       with Constant_Indexing => Constant_Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Comprehension     => (Empty     => Empty_Set,
-                                 Inclusion => Include);
+           Aggregate         => (Empty          => Empty_Set,
+                                 Add_Positional => Include);
 
+
 !discussion
 
 !ASIS
@@ -805,6 +887,205 @@
 I agree, we should use named and positional array aggregate syntax (and
 vocabulary) for these new container aggregates, unless there is a compelling
 reason to invent something new.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, January 19, 2018  1:28 PM
+
+I offered to take this one over from Florian, because he seems to be swamped 
+with other work, and I think this one is very important.  Essentially a
+complete re-write, using terms "positional" and "named" container aggregates.
+Also, introducing terms "element type" and "key type."  Hopefully it is
+understandable.
+
+[This is version /02 of the AI - ED.]
+Comments welcome!
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Friday, January 19, 2018   1:48 PM
+
+Looks great, a much-needed addition to the language!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, january 24, 2017  11:29 PM
+
+> Essentially a complete re-write, using terms "positional" and "named" 
+> container aggregates.
+
+A few comments:
+
+Are you using some funny editor/machine to create these attachments? They
+look normal when opened in Notepad, but when I try to cut-and-paste pieces
+(say into an e-mail message), the text comes out all on one line jammed
+together. Linux files don't even work in Notepad (are just one long line),
+so with those I know they need correction right away.
+
+At least reading them with an Ada program and writing them out again
+(Get_Line/Put_Line) makes a usable version.
+
+---
+
+There's some references in the proposal section to things that aren't going to
+be in *this* AI ("concurrent aggregates"), and "related changes" seems
+speculative at best. I'd just delete all of that.
+
+---
+
+> Given a private type or private extension T, the following 
+> type-related operational aspect may be specified:
+>
+>  Aggregate
+>    This aspect is of the form: 
+>    
+>      (Empty => name[,
+>       Add_Positional => /procedure_/name][,
+>       Add_Named => /procedure_/name])
+>       
+>    Either Add_Positional, Add_Named, or both shall be specified.
+
+It took me a long time to figure out that there isn't a need for special syntax
+here. I eventually realized that you are using a clever: this has the syntax of
+an aggregate, so this aspect is being specified by an expression.
+
+But this is a massive hack (and doesn't fit the rules given in 13.1.1,
+specifically 13.1.1(7/3) and 13.1.1(21/3)): this "expression" has no definable 
+type, could never resolve by conventional means, can't be "evaluated to a
+single value", doesn't match freezing rules, and probably more. I suppose your
+intent is that this would have to be implemented with aspect-specific code
+anyway, so it isn't a hardship to take an uninterpreted tree (required by 
+aspects anyway) and apply a custom interpretation to it.
+
+However, if we're going to use a clever hack here, we have to define it properly
+(with rule changes in 13.1.1). Also, we ought to do the same for other aspects.
+In particular, the Stable_Properties aspects (for which I defined new syntax to
+support lists of names, and which we already approved) probably should be
+defined as a typeless positional array aggregate. Also, the Default_Iterator
+and Iterator_Element probably should have a combined version (easier to use and
+test).
+
+Alternatively, we should simply (?) define a set of three interrelated aspects,
+as we did for those other existing aspects. I suspect the amount of work for
+this expression hack would be as much or more as defined three aspects. (At a
+minimum, one would need several pages of code just to check that the arbitrary
+expression that you are given actually is an aggregate, with 2 or 3 choices,
+that each of those choices is a name, that each of those choices is in named
+notation, that the names are the right ones... That would be extra code, not
+needed for separate aspects, probably much bigger than the checks that
+the Empty_Aggregate aspect was defined for the others.)
+
+---
+
+>If both Add_Positional and Add_Named are specified, the final 
+>parameters shall be of the same type -- the element type of T.
+
+This rule is given under Name Resolution Rules, but this is clearly a Legality
+Rule -- we never want to make resolution too smart. It should be moved.
+
+---
+
+> The expected type for a container_aggregate shall be a type for which 
+> the Aggregate aspect has been specified.  The expected type for each 
+> expression of a container_aggregate is the element type of the 
+> expected type.
+
+I don't think this works. All type aspects are independent of view
+(see 13.1.1(27/3)). As such, it also applies to the full view, and as such the
+common case of a full record type would define both record and container
+aggregates.
+
+I suppose we could use the "unless otherwise specified" exception, but I don't
+want to start making exceptions to type aspects, that opens a Pandora's box of
+anomalies. Besides, we don't (well, at least *I* don't) want container
+aggregates to disappear for full types that don't have aggregates of their
+own. It's just the conflict cases that need solution.
+
+[Aside: I think this is probably the right solution for prefixed names as
+well; allow the prefixed names to be used on operations that can see the full
+type, but only if they are defined for the private type, and only with the
+semantics of the private type -- thus a private type completed with an access
+type would allow prefixed calls, but a dereference of the access type would
+not be considered as a possible prefix. A bit wonky, perhaps, but worlds
+better than prefixed notation disappearing when a declaration is moved a few
+lines after the full type.]
+
+Anyway, I suggest that any type with a conflict be resolved in terms of using
+the built-in aggregates rather than the aspect. Perhaps:
+
+    The expected type for a container_aggregate shall be a type for which
+    the Aggregate aspect has been specified and which is not an array or record
+    type.
+
+---
+
+>  * for a named_container_aggregate for a type with an Add_Named procedure
+>    in its Aggregate aspect, the container_element_associations are evaluated
+>    in any order:
+
+I think the wording is "an unspecified order". It's this wording that triggers
+the anti-order-dependence checks of 6.4.1. There are several more of these.
+
+---
+
+>Examples
+>
+>I KNOW I NEED TO REWORK THESE TO USE EXISTING THINGS IN THE RM
+
+That's been in the AI for a while now, when is this happening?
+
+---
+
+>   --  Is (mostly, assuming set semantics) equivalent to
+>   S := (for Item in -5 .. 5 when Item /= 0 => Item);
+
+There are several examples using "when" in here; those should be removed from
+this AI which doesn't include "when" in the syntax.
+
+---
+
+There aren't any examples of named aggregates, I was trying to figure out the
+usage of the key_expression in an iterator and didn't find any.
+
+---
+
+>A.18.2 The Generic Package Containers.Vectors
+>
+>Add the Aggregate aspect to the existing ones on type Vector:
+>
+>   type Vector is tagged private
+>      with Constant_Indexing => Constant_Reference,
+>           Variable_Indexing => Reference,
+>           Default_Iterator  => Iterate,
+>           Iterator_Element  => Element_Type,
+>           Aggregate         => (Empty          => Empty_Vector,
+>                                 Add_Positional => Append);
+
+It might not be worth the effort, but it seems annoying that one cannot write
+named array aggregates for Vectors. After all, the idea is to make these as
+close to arrays as we can. It is especially annoying that one can't write an
+iterator for these:
+
+      (for I in 1..10 => I)
+
+to initialize a Vector with the values 1 through 10. (Since we just finally
+fixed this problem for regular array aggregates.)
+
+One possibility would be to define an Add_Named for this purpose, although
+we'd need a new length-expanding Insert operation for the purpose (since the
+order isn't defined). With that change, named aggregates could be written, but
+without ranges (other than in iterators), and without a check for missing
+elements (which seems like a bridge too far for this aspect in any case).
+
+---
+
+And that's all I've got. The basic ideas seem sound. And it is much more
+pleasant that the original version, having lost all of the terminology and
+feature gee-gaws that were jammed into the original proposal (and of which
+some vestiges remain).
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent