CVS difference for ai05s/ai05-0139-2.txt

Differences between 1.1 and version 1.2
Log of other versions for file ai05s/ai05-0139-2.txt

--- ai05s/ai05-0139-2.txt	2009/12/09 00:40:29	1.1
+++ ai05s/ai05-0139-2.txt	2009/12/29 05:55:40	1.2
@@ -1,4 +1,4 @@
-!standard 5.5                                       09-12-08  AI05-0139-2/01
+!standard 5.5                                       09-12-28  AI05-0139-2/02
 !class Amendment 09-02-13
 !status work item 09-02-13
 !status received 09-01-19
@@ -217,111 +217,6 @@
 as an element *of* the array/container rather than as an index or cursor
 *in* the sequence defined by the discrete range or iterator.
 
-USER DEFINED DEREFERENCE (AI05-141)
-
-The generic package Element_References might also be relevant to the
-notion of a user-defined "dereference" operation suggested in AI05-141. 
-One of the significant problems with AI05-141 as it stands is that there
-is no operation called when the dereference is "completed."  If we
-presume that the purpose of a user-defined dereference might be to
-implement some kind of software paging or persistence, then the page on
-which the designated object resides needs to be "pinned" in memory until
-the dereference is complete. But there is no user-defined cleanup
-routine provided in AI05-141. The Element_Reference and
-Element_Constant_Reference could provide for that, because they are
-derived from Limited_Controlled.
-
-So the suggestion is that, at least conceptually, there is an element
-reference object created, where the access discriminant comes from the
-result of the user-defined dereference, and when the resulting element
-reference object goes away, a user-defined cleanup routine would be
-called, perhaps to "unpin" the page on which the designated object
-resides.
-
-For practical reasons, rather than having the implementor of the storage
-pool provide extensions of Element_Reference and
-Element_Constant_Reference, they would instead just provide dereference
-operations similar to what is suggested in AI05-141, which takes in an
-"address" that might in fact not really be a machine address but rather
-an address-sized "locator" for the object that was returned by Allocate,
-and produces as a result a true machine address, suitable for use as the
-access discriminant of an element reference object.  There would be two
-of these operations, one for dereferencing an access-to-variable value,
-and one for dereferencing an access-to-constant value, and the work to
-be done might be quite different in the two cases (presuming, for
-instance, that the underlying storage pool is doing software paging). 
-In addition to the dereference operations, the implementor of the
-storage pool would provide two "cleanup" routines, which would be called
-when the hypothetical element reference object goes out of scope, again
-one for access-to-variable and one for access-to-constant.
-
-The import and export operations suggested in AI05-141 might still be
-provided for conversion to/from longer-lived access values.
-
-AI05-141 suggested that the dereference operation be accomplished
-through an IN-OUT parameter of type System.Address, allowing it to be
-the null procedure by default.  Given the number of operations we
-are now talking about, we would suggest defining a distinct
-("magic") descendant of Root_Storage_Pool that had these extra
-operations, two of which would more naturally be functions than procedures. The
-cleanup operations would ideally take three parameters, the storage
-pool, the original access value (which might not be a real machine
-address), and the "real" machine address produced by the dereference
-operation. Having both the original and the dereferenced value should
-simplify the cleanup operation.
-
-Here is a possible package System.Managed_Storage_Pools:
-
-    with System.Storage_Pools;
-    package System.Managed_Storage_Pools is
-        type Root_Managed_Storage_Pool is abstract new
-           Storage_Pools.Root_Storage_Pool with private;
-        
-        -- usual Allocate/Deallocate/Storage_Size routines,
-        -- inherited as abstract
-        
-        function Dereference(Pool : access Root_Managed_Storage_Pool; 
-          Access_Value : System.Address) return System.Address is abstract;
-          
-        function Constant_Dereference(Pool : access Root_Managed_Storage_Pool;
-          Access_Constant_Value : System.Address) return System.Address is abstract;
-          
-        procedure Cleanup_Dereference(Pool : access Root_Managed_Storage_Pool;
-          Access_Value : System.Address; Address_Value : System.Address) is null;
-          
-        procedure Cleanup_Constant_Dereference(Pool : access Root_Managed_Storage_Pool;
-          Access_Value : System.Address; Address_Value : System.Address) is null;
-          
-        function Export(Pool : access Root_Managed_Storage_Pool; 
-          Access_Value : System.Address) return System.Address is abstract;
-
-        function Import(Pool : access Root_Managed_Storage_Pool;
-          Address_Value : System.Address) return System.Address is abstract;
-          
-    private
-        -- not specified
-    end System.Managed_Storage_Pools;
-    
-Note that the use of element references is completely behind the scenes with
-this approach.  These access values work just like "regular" access values,
-but behind the scenes:
-
-  * on each dereference or conversion to an access parameter or
-    access discriminant they get temporarily made available as "true"
-    addresses via the user-defined dereference routines, and then get 
-    cleaned up.
-    
-  * on conversion to an access type that is not for an access parameter
-    or access discriminant, if the storage pool of the new access type
-    is different, they get permanently converted into a "normal"
-    address value via the Export function (which might raise PROGRAM_ERROR).
-    
-  * on conversion from an access type of a different storage pool, the
-    new access values are produced by calling the Import function, which might
-    raise PROGRAM_ERROR if importing from another storage pool is not
-    supported.
-
-    
 !wording [REMOVED FOR NOW]
 
 !discussion [NOT UPDATED -- SEE PROPOSAL FOR SOME NEWER DISCUSSION]
@@ -615,8 +510,176 @@
 !appendix
 
 From: Tucker Taft
-Sent: Tuesday, December  8, 2009  5:01 PM
 
+Thoughts on Iterators, 8-Nov-2009, for ARG meeting in St. Pete
+
+Relevant players in the game:
+
+  Container, Cursor, Iterator, Element.
+  
+-------------
+
+    for Element in [reverse] Container loop
+        ... -- body of loop
+    end loop;
+    
+is equiv to:
+
+    declare
+	Iterator : Iterator_Type := Iterate(Container);
+	Cursor : Cursor_Type := First(Iterator);
+    begin
+	while Has_Element(Cursor) loop
+	  declare
+	    Element : Element_Type renames Container(Cursor);
+	  begin
+	      ... -- body of loop	      
+	    Cursor := Next(Iterator, Cursor);
+	  end;
+	end loop;
+    end;
+
+or...
+
+    declare
+	Iterator : Iterator_Type := Iterate(Container);
+    begin
+	while More(Iterator) loop
+	  declare
+	    Cursor : Cursor_Type := Get_Next(Iterator'Access);
+	    Element : Element_Type renames Container(Cursor);
+	  begin
+	      ... -- body of loop	      
+	  end;
+	end loop;
+    end;   
+    
+---------
+
+    Container(Cursor)
+    
+  is equiv to:
+  
+    Element_{Ref,CRef}(Container, Cursor).Data.all
+    
+    for Cursor in Special_Iterator(Container) loop
+        Put(Container(Cursor));
+    end loop;
+    
+---------
+    
+    for Element in Container loop
+        Put(Element);
+    end loop;
+    
+ is equiv to:
+      
+    for Cursor in Default_Iterator(Container) loop
+      declare
+        Element : Element_Type renames Container(Cursor);
+      begin
+        Put(Element);
+      end;
+    end loop;
+    
+ similarly:
+ 
+    for Element in Array_Obj loop
+       Put(Element);
+    end loop;
+    
+ is equiv to:
+ 
+    for I in Array_Obj'Range(1) loop
+       for J in Array_Obj'Range(2) loop
+           ...
+         declare
+           Element : Array_Obj_Component_Type renames Array_Obj(I, J, ...);
+         begin
+           Put(Element);
+         end;
+           ...
+       end loop;
+   end loop;
+       
+
+---------
+
+    package Iterators is new Ada.Iterator_Interfaces(Cursor_Type, No_Element);
+    type Iterator_Type is new Iterators.Reversible_Iterator with ...
+    
+    package Containers is new 
+      Ada.Container_Interfaces(Iterators, Iterator_Type, Element_Type, Element_Reference);
+    type Container_Type is new Containers.Container with ...
+
+   generic
+       with package Iterators is new Ada.Iterator_Interfaces(<>);
+       type Iterator_Type is new Iterators.Reversible_Iterator with private;
+       type Element_Type(<>) is limited private;
+       type Element_Reference(Data : access Element_Type) is limited private;
+       type Element_Constant_Reference(Data : access constant Element_Type) is limited private;
+   package Ada.Container_Interfaces is
+       type Container is limited interface;
+       function Default_Iterator(C : Container) return Iterator_Type is abstract;
+       function Element_Ref(C : aliased in out Container; Cursor : Iterators.Cursor) 
+         return Element_Reference is abstract;
+       function Element_CRef(C : aliased in Container; Cursor : Iterators.Cursor) 
+         return Element_Constant_Reference is abstract;
+   end Ada.Container_Interfaces;
+   
+----------
+
+   generic
+       type Cursor is private;
+       No_Element : in Cursor;
+   package Ada.Iterator_Interfaces is
+
+       type Basic_Iterator is limited interface;
+       function First (Object : Basic_Iterator) return Cursor;
+       function Next (Object : Basic_Iterator; Position : Cursor) return Cursor;
+
+       type Reversible_Iterator is limited interface and Basic_Iterator;
+       function Last (Object : Reversible_Iterator) return Cursor;
+       function Previous (Object : Reversible_Iterator; Position : Cursor) return Cursor;
+
+   end Ada.Iterator_Interfaces;
+   
+****************************************************************
+
+From: Robert Dewar
+Sent: Sunday, November  8, 2009  10:26 AM
+
+Equivalent always makes me nervous. Are we sure we can make this strong a statement?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, November  8, 2009  11:40 AM
+
+This is more like the definition of "new T" when T has a user-defined storage pool.
+It is equivalent to a call on Allocate because its semantics are defined as calling
+Allocate.
+
+For the proposed syntax for iterators and indexing, their semantics will be defined
+in terms of calls on certain subprograms, etc.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Sunday, December  8, 2009  1:14 PM
+
+> This is more like the definition of "new T" when T has a user-defined 
+> storage pool.  It is equivalent to a call on Allocate because its 
+> semantics are defined as calling Allocate.
+
+I think it is fine to say "the behavior is as though xyz was called bla bla".
+I just think we often get ourselves in trouble if the formal definition uses the
+word equivalent, it's such a strong word from a formal point of view.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December  8, 2009  5:01 PM
 
 Here is a new variant for AI05-139 on user-defined iterators, etc.  [This is
 version /01 of this AI - ED.] It is based on all the earlier proposals,

Questions? Ask the ACAA Technical Agent