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

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

--- ai12s/ai12-0266-1.txt	2019/01/11 04:15:26	1.10
+++ ai12s/ai12-0266-1.txt	2019/01/11 08:27:41	1.11
@@ -1,4 +1,4 @@
-!standard 5.5.1(4/3)                                  19-01-09  AI12-0266-1/07
+!standard 5.5.1(4/3)                                  19-01-10  AI12-0266-1/08
 !standard 5.5.1(6/4)
 !standard 5.5.1(11/3)
 !standard 5.5.2(4/3)
@@ -21,8 +21,8 @@
 
 !proposal
 
-This proposal depends on the facilities for parallel loops (AI12-0119-1)
-and for aspect Nonblocking (AI12-0064-2).
+This proposal depends on the facilities for parallel loops (AI12-0119-1),
+chunk specifications (AI12-0251-1), and for aspect Nonblocking (AI12-0064-2).
 
 The goals of this proposal are:
 - To extend parallel iteration to the standard container libraries
@@ -64,70 +64,94 @@
 
 !wording
 
-Replace 5.5(3/3)
+Replace 5.5(3/5) with:
 
-Iteration_scheme ::= while condition
-   | [parallel] for loop_parameter_specification
-   | [parallel] for iterator_specification
-
-Modify 5.5.1 (2/5)
- generic
-   type Cursor;
-   with function Has_Element (Position : Cursor) return Boolean;
-package Ada.Iterator_Interfaces is
-   with Pure, Nonblocking => {Cursor'Nonblocking and Has_Element'Nonblocking}[False] is
+  iteration_scheme ::= while condition
+     | for loop_parameter_specification
+     | for iterator_specification
+     | parallel [(chunk_specification)]
+       for loop_parameter_specification
+     | parallel [(chunk_specification)]
+       for iterator_specification
 
-Add after 5.5.1(4/3)
+Add after 5.5.1(4/3):
 
-   type Parallel_Iterator is limited interface and Forward_Iterator;
+   type Parallel_Iterator is limited interface and Forward_Iterator
+      with Nonblocking => Cursor'Nonblocking and Has_Element'Nonblocking;
 
    subtype Chunk_Index is Positive;
 
-   function Is_Split
-     (Object : Parallel_Iterator) return Boolean is abstract;
+   function Is_Split (Object : Parallel_Iterator)
+      return Boolean is abstract
+      with Nonblocking => Parallel_Iterator'Nonblocking;
+
+   procedure Split_Into_Chunks (Object     : in out Parallel_Iterator;
+                                Max_Chunks : Chunk_Index) is abstract
+      with Nonblocking => Parallel_Iterator'Nonblocking,
+           Pre'Class   => not Object.Is_Split or else raise Program_Error,
+           Post'Class  => Object.Is_Split and then
+              Object.Chunk_Count <= Max_Chunks;
+
+   function Chunk_Count (Object : Parallel_Iterator) return Chunk_Index
+      is abstract
+      with Nonblocking => Parallel_Iterator'Nonblocking,
+           Pre'Class   => Object.Is_Split or else raise Program_Error;
+
+   function First_In_Chunk (Object : Parallel_Iterator;
+                            Chunk  : Chunk_Index) return Cursor is abstract
+      with Nonblocking => Parallel_Iterator'Nonblocking,
+           Pre'Class   => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
+                           or else raise Program_Error;
+
+   function Next_In_Chunk (Object   : Parallel_Iterator;
+                           Position : Cursor;
+                           Chunk    : Chunk_Index) return Cursor is abstract
+      with Nonblocking => Parallel_Iterator'Nonblocking,
+           Pre'Class   => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
+                           or else raise Program_Error;
+
+   overriding
+   function First Object : Parallel_Iterator) return Cursor is abstract
+      with Nonblocking => Parallel_Iterator'Nonblocking;
+
+   overriding
+   function Next (Object   : Parallel_Iterator;
+                  Position : Cursor) return Cursor is abstract
+      with Nonblocking => Parallel_Iterator'Nonblocking;
+
+   [Editor's note: We need the above overridings to make these routines
+   Nonblocking, else they would allow blocking as inherited from their
+   ancestors.]
 
-   procedure Split_Into_Chunks
-     (Object     : in out Parallel_Iterator;
-      Max_Chunks : Chunk_Index) is abstract
-     with
-       Pre'Class  => not Object.Is_Split or else raise Program_Error,
-         Post'Class => Object.Is_Split and then
-         Object.Chunk_Count <= Max_Chunks;
-
-   function Chunk_Count
-     (Object : Parallel_Iterator) return Chunk_Index is abstract
-     with Pre'Class => Object.Is_Split or else raise Program_Error;
-
-   function First_In_Chunk
-     (Object : Parallel_Iterator;
-      Chunk  : Chunk_Index) return Cursor is abstract
-     with Pre'Class => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
-                        or else raise Program_Error;
-
-   function Next_In_Chunk
-     (Object   : Parallel_Iterator;
-      Position : Cursor;
-      Chunk    : Chunk_Index) return Cursor is abstract
-     with Pre'Class => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
-                        or else raise Program_Error;
-
    type Parallel_Reversible_Iterator is limited interface
-     and Parallel_Iterator and Reversible_Iterator;
+      and Parallel_Iterator and Reversible_Iterator
+      with Nonblocking => Parallel_Iterator'Nonblocking;
+
+   function Last_In_Chunk (Object : Parallel_Reversible_Iterator;
+                           Chunk  : Chunk_Index) return Cursor is abstract
+      with Nonblocking => Parallel_Reversible_Iterator'Nonblocking,
+           Pre'Class   => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
+                           or else raise Program_Error;
+
+   function Previous_In_Chunk (Object   : Parallel_Reversible_Iterator;
+                               Position : Cursor;
+                               Chunk    : Chunk_Index) return Cursor is abstract
+
+      with Nonblocking => Parallel_Reversible_Iterator'Nonblocking,
+           Pre'Class   => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
+                           or else raise Program_Error;
+
+   overriding
+   function Last (Object : Parallel_Reversible_Iterator) return Cursor is abstract
+      with Nonblocking => Parallel_Reversible_Iterator'Nonblocking;
+
+   overriding
+   function Previous (Object   : Parallel_Reversible_Iterator;
+                      Position : Cursor) return Cursor is abstract
+      with Nonblocking => Parallel_Reversible_Iterator'Nonblocking;
 
-   function Last_In_Chunk
-     (Object : Parallel_Reversible_Iterator;
-      Chunk  : Chunk_Index) return Cursor is abstract
-     with Pre'Class => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
-                        or else raise Program_Error;
-
-   function Previous_In_Chunk
-     (Object   : Parallel_Reversible_Iterator;
-      Position : Cursor;
-      Chunk    : Chunk_Index) return Cursor is abstract
-     with Pre'Class => (Object.Is_Split and then Chunk <= Object.Chunk_Count)
-                        or else raise Program_Error;
 
-Modify 5.5.1(6/3)
+Modify 5.5.1(6/3):
 
 An iterator type is a type descended from the Forward_Iterator
 interface from some instance of Ada.Iterator_Interfaces. A reversible iterator
@@ -143,7 +167,7 @@
 The formal subtype Cursor from the associated instance of
 Ada.Iterator_Interfaces is the iteration cursor subtype for the iterator type.
 
-Modify 5.5.1(11/3)
+Modify 5.5.1(11/3):
 
 An iterable container type is an indexable container type with specified
 Default_Iterator and Iterator_Element aspects. A reversible iterable container
@@ -158,7 +182,7 @@
 iterable container type. A parallel reversible iterable container object is an
 object of a parallel reversible iterable container type.}
 
-Modify 5.5.2(4/3)
+Modify 5.5.2(4/3):
 
 If the reserved word reverse appears, the iterator_specification is a reverse
 iterator{.}[;] {If the reserved word parallel appears, the
@@ -171,7 +195,7 @@
 element iterator, the default iterator type for the type of the iterable_name
 shall be of a parallel iterator type or a parallel reversible iterator type.}
 
-Modify AARM 5.5.2(8.a/5)
+Modify AARM 5.5.2(8.a/5):
 
 Ramification: The loop parameter{s} of a generalized iterator {have}[has] the
 same accessibility as the loop statement. This means that the loop parameter
@@ -189,7 +213,7 @@
 sequence_of_statements; the accessibility of the loop parameter{s are} [is] that
 of the block statement.
 
-Modify 5.5.2(10/3)
+Modify 5.5.2(10/3):
 
 For a generalized iterator, the loop parameter{s are} [is] created, the
 iterator_name is evaluated, and the denoted iterator object becomes the
@@ -205,7 +229,7 @@
 generalized iterator, the operations Last and Previous are called rather than
 First and Next.
 
-Add after 5.5.2(10/3)
+Add after 5.5.2(10/3):
 
 For a parallel generalized iterator, the operation Split_Into_Chunks of the
 iterator type is then called, with the Max_Chunks parameter specified as the
@@ -234,7 +258,7 @@
 determined. For instance, a tree based container might create the split based on
 the number of branches at the top levels of the tree.
 
-Modify AARM 5.5.2(10.a/4)
+Modify AARM 5.5.2(10.a/4):
 
 Ramification: The loop parameter{s} of a generalized iterator [is a]{are}
 variable{s} of which the user only has a constant view. It follows the normal
@@ -245,7 +269,7 @@
 subsequent iteration if Next [or]{,} Previous{, Next_In_Chunk, or
 Previous_In_Chunk} return an object with a different tag or constraint.
 
-Modify 5.5.2(11/3)
+Modify 5.5.2(11/3):
 
 For an array component iterator, the iterable_name is evaluated and the denoted
 array object becomes the array for the loop. If the array for the loop is a null
@@ -265,7 +289,7 @@
 of the array for the loop, or until the loop is left as a consequence of a
 transfer of control.
 
-Modify 5.5.2(12/3)
+Modify 5.5.2(12/3):
 
 For a container element iterator, the iterable_name is evaluated and the denoted
 iterable container object becomes the iterable container object for the loop.
@@ -274,7 +298,7 @@
 iterator. [An object] {Objects} of the default cursor subtype [is]{are} created
 (the loop cursor{s}).
 
-Modify 5.5.2(13/3) [into two paragraphs]
+Modify 5.5.2(13/3): [into two paragraphs]
 
 For a forward container element iterator, the operation First of the iterator
 type is called on the loop iterator, to produce the initial value for the loop
@@ -309,7 +333,7 @@
 the type of the iterable container object for the
 loop; otherwise it uses the default variable indexing function.
 
-Modify 5.5.2(15/3)
+Modify 5.5.2(15/3):
 
 -- Array component iterator example:
 {parallel}
@@ -318,22 +342,22 @@
 end loop;
 
 
-Modify A.18.2(74.1/3)
+Modify A.18.2(74.1/3):
 
 function Iterate (Container : in Vector)
       return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.2(74.2/3)
+Modify A.18.2(74.2/3):
 
 function Iterate (Container : in Vector; Start : in Cursor)
       return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.2(230.1/3)
+Modify A.18.2(230.1/3):
 
 function Iterate (Container : in Vector)
    return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.2(230.2/3)
+Modify A.18.2(230.2/3):
 
 Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
 generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in
@@ -347,12 +371,12 @@
 loop_statement whose iterator_specification denotes this object). The iterator
 object needs finalization.
 
-Modify A.18.2(230.3/3)
+Modify A.18.2(230.3/3):
 
 function Iterate (Container : in Vector; Start : in Cursor)
    return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.2(230.4/3)
+Modify A.18.2(230.4/3):
 
 If Start is not No_Element and does not designate an item in Container, then
 Program_Error is propagated. If Start is No_Element, then Constraint_Error is
@@ -367,22 +391,22 @@
 loop_statement whose iterator_specification denotes this object). The iterator
 object needs finalization.
 
-Modify A.18.3(46.1/3)
+Modify A.18.3(46.1/3):
 
 function Iterate (Container : in List)
       return List_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.3(46.2/3)
+Modify A.18.3(46.2/3):
 
 function Iterate (Container : in List; Start : in Cursor)
       return List_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.3(144.1/3)
+Modify A.18.3(144.1/3):
 
 function Iterate (Container : in List)
    return List_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.3(144.2/3)
+Modify A.18.3(144.2/3):
 
 Iterate returns a {parallel }reversible iterator object (see 5.5.1) that will
 generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in
@@ -396,12 +420,12 @@
 loop_statement whose iterator_specification denotes this object). The iterator
 object needs finalization.
 
-Modify A.18.3(144.3/3)
+Modify A.18.3(144.3/3):
 
 function Iterate (Container : in List; Start : in Cursor)
    return List_Iterator_Interfaces.Parallel_Reversible_Iterator'Class;
 
-Modify A.18.3(144.4/3)
+Modify A.18.3(144.4/3):
 
 If Start is not No_Element and does not designate an item in Container, then
 Program_Error is propagated. If Start is No_Element, then Constraint_Error is
@@ -416,17 +440,17 @@
 sequence_of_statements of the loop_statement whose iterator_specification
 denotes this object). The iterator object needs finalization.
 
-Modify A.18.5(37.1/3)
+Modify A.18.5(37.1/3):
 
 function Iterate (Container : in Map)
       return Map_Iterator_Interfaces.{Parallel_}[Forward_]Iterator'Class;
 
-Modify A.18.5(61.1/3)
+Modify A.18.5(61.1/3):
 
 function Iterate (Container : in Map)
    return Map_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
 
-Modify A.18.5(61.2/3)
+Modify A.18.5(61.2/3):
 
 Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate
 [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each node in
@@ -439,22 +463,22 @@
 iterator_specification denotes this object). The iterator object needs
 finalization.
 
-Modify A.18.6(51.1/3)
+Modify A.18.6(51.1/3):
 
 function Iterate (Container : in Map)
       return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.6(51.2/3)
+Modify A.18.6(51.2/3):
 
 function Iterate (Container : in Map; Start : in Cursor)
       return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.6(94.1/3)
+Modify A.18.6(94.1/3):
 
 function Iterate (Container : in Map)
    return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.6(94.2/3)
+Modify A.18.6(94.2/3):
 
 Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
 generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each
@@ -468,12 +492,12 @@
 sequence_of_statements of the loop_statement whose iterator_specification
 denotes this object). The iterator object needs finalization.
 
-Modify A.18.6(94.3/3)
+Modify A.18.6(94.3/3):
 
 function Iterate (Container : in Map; Start : in Cursor)
    return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.6(94.4/3)
+Modify A.18.6(94.4/3):
 
 If Start is not No_Element and does not designate an item in Container, then
 Program_Error is propagated. If Start is No_Element, then Constraint_Error is
@@ -489,17 +513,17 @@
 iterator_specification denotes this object). The iterator object needs
 finalization.
 
-Modify A.18.8(49.1/3)
+Modify A.18.8(49.1/3):
 
 function Iterate (Container : in Set)
       return Set_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
 
-Modify A.18.8(85.1/3)
+Modify A.18.8(85.1/3):
 
 function Iterate (Container : in Set)
    return Set_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
 
-Modify A.18.8(85.2/3)
+Modify A.18.8(85.2/3):
 
 Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate
 [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element in
@@ -512,22 +536,22 @@
 iterator_specification denotes this object). The iterator object needs
 finalization.
 
-Modify A.18.9(61.1/3)
+Modify A.18.9(61.1/3):
 
 function Iterate (Container : in Set)
       return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.9(61.2/3)
+Modify A.18.9(61.2/3):
 
 function Iterate (Container : in Set; Start : in Cursor)
       return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.9(113.1/3)
+Modify A.18.9(113.1/3):
 
 function Iterate (Container : in Set; Start : in Cursor)
       return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.9(113.2/3)
+Modify A.18.9(113.2/3):
 
 Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
 generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each
@@ -542,12 +566,12 @@
 iterator_specification denotes this object). The iterator object needs
 finalization.
 
-Modify A.18.9(113.3/3)
+Modify A.18.9(113.3/3):
 
 function Iterate (Container : in Set; Start : in Cursor)
    return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
 
-Modify A.18.9(113.4/3)
+Modify A.18.9(113.4/3):
 
 If Start is not No_Element and does not designate an item in Container, then
 Program_Error is propagated. If Start is No_Element, then Constraint_Error is
@@ -563,17 +587,17 @@
 loop_statement whose iterator_specification denotes this object). The iterator
 object needs finalization.
 
-Modify A.18.10(44/3)
+Modify A.18.10(44/3):
 
 function Iterate (Container : in Tree)
       return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
 
-Modify A.18.10(45/3)
+Modify A.18.10(45/3):
 
 function Iterate_Subtree (Position : in Cursor)
       return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
 
-Modify A.18.10(156/3)
+Modify A.18.10(156/3):
 
 function Iterate (Container : in Tree)
    return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
@@ -591,12 +615,12 @@
 iterator_specification denotes this object). The iterator object needs
 finalization.
 
-Modify A.18.10(158/3)
+Modify A.18.10(158/3):
 
 function Iterate_Subtree (Position : in Cursor)
    return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
 
-Modify A.18.10(159/3)
+Modify A.18.10(159/3):
 
 If Position equals No_Element, then Constraint_Error is propagated. Otherwise,
 Iterate_Subtree returns a[n] {parallel} iterator object (see 5.5.1) that will
@@ -1999,6 +2023,92 @@
   more similar to the existing iterator interfaces
 - Added a Last_In_Chunk and Previous_In_Chunk call for
   Parallel_Reversible_Iterator_Interfaces
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 10, 2019  10:46 PM
+
+> Attached is my homework for AI12-0266-01, Parallel Container
+> Iterators.
+
+Editorial fixes applied:
+
+The first bullet under "goals of this proposal" needs to end with a semicolon
+";" like the later bullets.
+
+All of the Modify and Adds need colons at the end (":"). If I'm going to
+complain to Justin, I have to complain to you, too. ;-)
+
+The way you dealt with parameters on multiple lines is not the way the RM
+typically does it (I checked Containers, Text_IO, and Calendar):
+
+-- RM:
+    procedure Foo (A : in Natural;
+                   B : in String);
+
+-- You:
+    procedure Foo
+      (A : in Natural;
+       B : in String);
+
+I had to adjust all of the specs for the Nonblocking anyway (see below), so I
+fixed this now.
+
+
+Technical issues (fixed in version /08, a minor redraft):
+
+The grammar for 5.5(3) was extensively changed by AI12-0251-1. This grammar
+change needs to reflect that. If we didn't take AI12-0251-1 and AI12-0294-1 into
+account here (otherwise we'd have to write a new AI nearly as big as this one to
+change everything to match that). See more below in stuff I *didn't* do.
+
+---
+
+I gave you the wrong info about Nonblocking. We can't change the instance
+Nonblocking, as that could be incompatible with existing code. (That is, if the
+generic formals are Nonblocking, then the overriding routines  for the base
+interfaces could not allow blocking (Nonblocking => False). But that's the
+default for Nonblocking, so such a change would reject code that is currently
+legal.
+
+I was thinking that this was in a separate generic, but obviously it isn't.
+
+Therefore, we have to put the Nonblocking spec on each individual subprogram
+declared for the parallel interface. (Unlike the others, we can get the
+Nonblocking right here, as there is no compatibility problem. Most
+implementations will require Nonblocking => True, but that's a good thing!)
+
+---
+
+Modify AARM 5.5.2(8.a/5) and move into the Dynamic Semantics section after 5.5.2
+
+I don't know why you added this move; the note is a Ramification of the way the
+loop parameters are declared (which determines their lifetime); while the
+consequences are dynamic semantics, the reason that they occur is because of the
+static semantics. That can't change just because of the parallel keyword, if you
+believe that is not true then we need wording to actually make this requirement.
+
+I left the note where is was, pending further justification.
+
+---
+
+
+
+Technical issues (not handled but very important):
+
+You failed to reconcile the AI with the extensive changes to add chunk
+specifications. The syntax and semantics in 5.5 were changed substantially, and
+you need to hook your stuff to that. In particular, you need to explain that
+Max_Chunks comes from the value evaluated for the chunk_specification if one is
+present, and that it is implementation-defined otherwise. (That definition of
+Max_Chunks). And if there is a chunk_parameter, you have to define how that maps
+to the chunks returned from this interface.
+
+You probably can steal some of the revised wording -- that's all in the latest
+RM draft. (If you don't have it yet, you ought to be able to download it soon.)
+
+That was too much for me to do tonight, so I'm leaving it for someone else.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent