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

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

--- ai05s/ai05-0139-2.txt	2010/05/20 02:56:40	1.6
+++ ai05s/ai05-0139-2.txt	2010/06/13 00:59:17	1.7
@@ -1,4 +1,9 @@
-!standard 5.5                                       10-05-18  AI05-0139-2/05
+!standard 4.1(2/2)                                    10-06-10  AI05-0139-2/06
+!standard 4.1.5(0)
+!standard 4.1.6(0)
+!standard 5.5(3)
+!standard 5.5(9)
+!standard 5.5.1(0)
 !class Amendment 09-02-13
 !status work item 09-02-13
 !status received 09-01-19
@@ -182,10 +187,10 @@
 aspects, if it helps in understanding the model.
 
 If only the Variable_Indexing aspect is defined, then indexing
-may only be applied to variables.  If only the Constant_Indexing
+may only be applied to variables. If only the Constant_Indexing
 aspect is defined then indexing may be applied to a variable or
 a constant, but not in a context that requires the result to be
-a variable.  If both aspects are defined, then the Variable_Indexing
+a variable. If both aspects are defined, then the Variable_Indexing
 aspect is used when the indexing is used in a context that requires
 a variable, or in an object renaming where the prefix is a variable;
 the Constant_Indexing aspect is used otherwise.
@@ -330,7 +335,7 @@
          Variable_Indexing => Element,
          Constant_Indexing => Element_RO,
          Default_Iterator  => Iterate,
-         Iterator_Element  => Element;
+         Iterator_Element  => Element_Type;
 
     type Element_Ref(E : access Element_Type) is limited
       new Ada.References.Reference with private;
@@ -413,8 +418,369 @@
 
 !wording
 
-** TBD **
+[NOTE for editor: I am using /xyzzy/ to mean italicized xyzzy.]
 
+Revise 4.1(2/3) as follows:
+
+  name ::=
+     direct_name | explicit_dereference
+   | indexed_component | slice
+   | selected_component | attribute_reference
+   | type_conversion | function_call
+   | character_literal | qualified_expression
+  {| generalized_reference | generalized_indexing}
+
+Add a new section 4.1.5:
+
+  4.1.5 User-Defined References
+
+  The following language-defined library package exists:
+
+     package Ada.References is
+         type Reference is limited interface;
+     end Ada.References;
+
+  A /reference type/ is a user-defined tagged type which has exactly one
+  access discriminant and is descended from the language-defined
+  interface type Ada.References.Reference. A /reference object/ is an
+  object of a reference type. [Redundant: A generalized_reference is a
+  name that denotes the object or subprogram designated by the access
+  discriminant of a reference object.]
+
+          Syntax
+
+    generalized_reference ::= /reference_object_/name
+
+          Name Resolution
+
+  The expected type for the /reference_object_/name in a generalized_reference
+  is expected to be of any reference type.
+
+          Static Semantics
+
+  A generalized_reference denotes a view equivalent to that of a dereference
+  of the access discriminant of the named reference object.
+
+          Dynamic Semantics
+
+  The evaluation of a generalized_reference consists of the evaluation
+  of the /reference_object_/name and a determination of the object or
+  subprogram designated by the access discriminant of the named
+  reference object. A check is made that the value of the access
+  discriminant is not the null access value. Constraint_Error is raised
+  if this check fails. The generalized_reference denotes the object or
+  subprogram designated by the value of the access discriminant of the
+  named reference object.
+
+           Example
+
+  type Ref_Element(Data : access Element) is
+    new Ada.Finalization.Limited_Controlled
+      and Ada.References.Reference with null record;
+        -- This type is now a "reference" type
+
+  function Find(C : access Container; Key : String) return Ref_Element;
+    -- Return a reference to an element of a container
+
+  ...
+
+  Find(C, "abc") := Element'(...);  -- Assign through a reference
+
+  -- This is equivalent to:
+  --   Find(C, "abc").Data.all := Element'(...);
+
+
+Add a new section 4.1.6:
+
+  4.1.6 User-Defined Indexing
+
+  Given a tagged type T, the following aspects may be specified:
+
+  Constant_Indexing  This aspect shall be specified by a name that
+    denotes one or more functions declared immediately within the same
+    declaration list in which T is declared. All of such functions shall
+    have at least two parameters, the first of which is of type T or
+    T'Class, or is an access-to-constant parameter with designated type
+    T or T'Class.
+
+  Variable_Indexing  This aspect shall be specified by a name that
+    denotes one or more functions declared immediately within the same
+    declaration list in which T is declared. All of such functions shall
+    have at least two parameters, the first of which is of type T or
+    T'Class, or is an access parameter with designated type T or T'Class.
+    All of such functions shall have a return type that is a reference
+    type (see 4.1.5), whose access discriminant is of an
+    access-to-variable type.
+
+  These aspects are inherited by descendants of T (including the class-wide
+  type T'Class). The aspects may not be overridden, but the functions they
+  denote may be.
+
+  An /indexable type/ is a user-defined tagged type with at least one of
+  the aspects Constant_Indexing or Variable_Indexing specified. An
+  /indexable object/ is an object of an indexable type. [Redundant: A
+  generalized_indexing is a name that denotes the result of calling a
+  function named by a Contant_Indexing or Variable_Indexing aspect.]
+
+            Syntax
+
+  generalized_indexing ::= /indexable_object_/prefix actual_parameter_part
+
+            Name Resolution
+
+  The expected type for the /indexable_object_/prefix of a generalized_indexing
+  is any indexable type.
+
+  If the Constant_Indexing aspect is specified for the type of the
+  /indexable_object_/prefix of a general_indexing, then the general_indexing
+  is interpreted as a /constant indexing/ under the following circumstances:
+
+    * when the Variable_Indexing aspect is not specified for the type
+      of the /indexable_object_/prefix;
+
+    * when the /indexable_object_/prefix denotes a constant;
+
+    * when the generalized_indexing is used within a primary
+      where a name denoting a constant is permitted.
+
+      AARM NOTE: This means it is not interpreted as a
+        constant_indexing for the /variable_/name in the LHS of an
+        assignment (not inside a primary), nor for the name used for an
+        OUT or IN OUT parameter (not allowed to be a constant), nor for
+        the name in an object renaming (not inside a primary), unless
+        there is no Variable_Indexing aspect defined.
+
+  Otherwise, the general_indexing is interpreted as a /variable indexing/.
+
+  When a general_indexing is interpreted as a constant (or variable) indexing,
+  it is equivalent to a call on a prefixed view of one of the functions named
+  by the Constant_Indexing (or Variable_Indexing) aspect of the type of the
+  /indexable_object_/prefix with the given actual_parameter_part, and with
+  the /indexable_object_/prefix as the prefix of the prefixed view.
+
+  AARM NOTE: In other words, the generalized_indexing is equivalent to:
+
+       /indexable_object_/prefix.Indexing actual_parameter_part
+
+     where Indexing is the name specified for the Constant_Indexing or
+     Variable_Indexing aspect.
+
+Revise paragraph 5.5(3):
+
+  iteration_scheme ::= while condition
+   | for loop_parameter_specification
+  {| for iterator_specification}
+
+Revise the first sentence of paragraph 5.5(9):
+
+  For the execution of a loop_statement with [a FOR iteration_scheme]
+  {the iteration_scheme being FOR loop_parameter_specification}, the
+  loop_parameter_specification is first elaborated. ...
+
+Add a new section 5.5.1:
+
+  5.5.1 User-Defined Iterators
+
+  The following language-defined generic library package exists:
+
+   generic
+       type Cursor is private;
+       No_Element : in Cursor;
+   package Ada.Iterator_Interfaces is
+
+       type Forward_Iterator is limited interface;
+       function First (Object : Forward_Iterator) return Cursor;
+       function Next (Object : Forward_Iterator; Position : Cursor) return Cursor;
+
+       type Reversible_Iterator is limited interface and Forward_Iterator;
+       function Last (Object : Reversible_Iterator) return Cursor;
+       function Previous (Object : Reversible_Iterator; Position : Cursor) return Cursor;
+
+   end Ada.Iterator_Interfaces;
+
+              Static Semantics
+
+   An /iterator type/ is a type descended from the Forward_Iterator interface
+   from some instance of Ada.Iterator_Interfaces. A /reversible iterator type/
+   is a type descended from the Reversible_Iterator interface from some instance
+   of Ada.Iterator_Interfaces. A /(reversible) iterator object/ is an object
+   of a (reversible) iterator type. The formal subtype Cursor from the associated
+   instance of Ada.Iterator_Interfaces is the /iteration cursor subtype/ for the
+   iterator type.
+
+   The following aspects may be specified for an indexable type T (see 4.1.6):
+
+     Default_Iterator  This aspect is specified by a name that denotes
+       exactly one function declared immediately within the same
+       declaration list in which T is declared, whose first parameter is
+       of type T or T'Class or an access parameter whose designated type
+       is type T or T'Class, whose other parameters, if any, have
+       default expressions, and whose result type is an iterator type.
+       This function is the /default iterator function/ for T. Its
+       result subtype is the /default iterator subtype/ for T. The
+       iteration cursor subtype for the default iterator subtype is the
+       /default cursor subtype/ for T.
+
+     Iterator_Element  This aspect is specified by a name that denotes
+       a subtype. This is the /default element subtype/ for T.
+
+
+   These aspects are inherited by descendants of type T (including T'Class).
+
+   An /iteratable type/ is an indexable type with specified Default_iterator and
+   Iterator_Element aspects. A /reverse iteratable type/ is an
+   iteratable type with the default iterator type being a reversible
+   iterator type. A /(reverse) iteratable object/ is an object of a
+   (reverse) iteratable type.
+
+             Legality Rules
+
+   The Constant_Indexing aspect (if any) of an iteratable type T
+   shall denote exactly one function with the following properties:
+
+      * the result type of the function is covered by
+        the default element type of T or is a reference type
+        (see 4.1.5) with an access discriminant designating
+        a type covered by the default element type of T;
+      * the type of the second parameter of the function covers the
+        default cursor type for T;
+      * if there are more than two parameters, the additional
+        parameters all have default expressions.
+
+   This function (if any) is the /default constant indexing function/
+   for T.
+
+   The Variable_Indexing aspect (if any) of an iteratable type T
+   shall denote exactly one function with the following properties:
+
+      * the result type of the function is a reference type
+        (see 4.1.5) with an access discriminant designating
+        a type covered by the default element type of T;
+      * the type of the second parameter of the function covers the
+        default cursor type for T;
+      * if there are more than two parameters, the additional
+        parameters all have default expressions.
+
+   This function (if any) is the /default variable indexing function/
+   for T.
+
+               Syntax
+
+   iterator_specification ::=
+      defining_identifier IN [REVERSE] /iterator_/name
+    | defining_identifier [: subtype_indication] OF [REVERSE] /array_/name
+    | defining_identifier [: subtype_indication] OF [REVERSE] /iteratable_/name
+
+               Name Resolution
+
+   In an iterator_specification, the expected type for the
+   /iterator_/name is any iterator type; the expected type for the
+   /array_/name is any array type; the expected type for the
+   /iteratable_/name is any iteratable type.
+
+               Legality Rules
+
+   If the reserved word REVERSE appears in the first form of
+   iterator_specification, then the /iterator_/name shall be of a
+   reversible iterator type. The type of the /array_/name in the second
+   form of iterator_specification shall be a one-dimensional array type.
+   If the reserved word REVERSE appears in the third form of
+   iterator_specification, the default iterator type for the type of the
+   /iteratable_/name shall be a reversible iterator type.
+
+   The type of the subtype_indication, if any, of the second form of
+   iterator_specification shall cover the component type of the type of
+   the /array_/name. The type of the subtype_indication, if any, of the
+   third form of iterator_specification shall cover the default element
+   type for the type of the /iteratable_/name.
+
+   In the third form of iterator_specification, if the /iteratable_/name
+   denotes a constant, then the Constant_Indexing aspect shall be specified
+   for the type of the /iteratable_/name.
+
+            Static Semantics
+
+   An iterator_specification declares a /loop parameter/. In the first
+   form of iterator_specification, the nominal subtype of the loop
+   parameter is the iterator cursor subtype. In the second and third
+   form of iterator_specification, if a subtype_indication is present,
+   it determines the nominal subtype of the loop parameter. In the
+   second form if a subtype_indication is not present, the nominal
+   subtype of the loop parameter is the component subtype of the type of
+   the /array_/name. In the third form if a subtype_indication is
+   not present, the nominal subtype of the loop parameter is the default
+   element subtype for the type of the /iteratable_/name.
+
+   In the second form of iterator_specification, the loop parameter
+   denotes a constant if the /array_/name denotes a constant; otherwise
+   it denotes a variable. In the third form of iterator_specification,
+   the loop parameter denotes a constant if the /iteratable_/name
+   denotes a constant, or if the Variable_Indexing aspect is not
+   specified for the type of the /iteratable_/name; otherwise it denotes
+   a variable.
+
+            Dynamic Semantics
+
+   For the execution of a loop_statement with an iterator_specification,
+   the iterator_specification is first elaborated. This elaboration
+   elaborates the subtype_indication, if any.
+
+   For the first form of iterator_specification, the loop parameter is
+   created, and the /iterator_/name is evaluated and the denoted
+   iterator object becomes the /loop iterator/. If the reserved word
+   REVERSE does not appear (does appear), then the operation First
+   (Last) of the (reversible) iterator type is called on the loop
+   iterator, to produce the initial value for the loop parameter. If the
+   initial value is equal to No_Element, then the execution of the
+   loop_statement is complete.  Otherwise, the sequence_of_statements is
+   executed and then the Next (Previous) operation of the (reversible)
+   iterator type is called with the loop iterator and the current value
+   of the loop parameter to produce the next value to be assigned to the
+   loop parameter. This repeats until the loop parameter is equal to
+   No_Element, or the loop is left as a consequence of a transfer of
+   control.
+
+   For the second form of iterator_specification, the /array_/name is
+   evaluated and the array object denoted by the name becomes the /array
+   for the loop/. If the array for the loop is a null array, then the
+   execution of the loop_statement is complete. Otherwise, if the
+   reserved word REVERSE does not appear (does appear), then the
+   sequence_of_statements is executed with the loop parameter denoting
+   the first (last) element of the array for the loop. If the loop
+   parameter now denotes the last (first) element of the array for the
+   loop, then the execution of the loop_statement is complete.
+   Otherwise, the sequence_of_statements is executed again with the loop
+   parameter denoting the next (previous) element of the array for the
+   loop. This repeats until the last (first) element is processed, or
+   until the loop is left as a consequence of a transfer of control.
+
+   For the third form of iterator_specification, the /iteratable_/name
+   is evaluated and the iteratable object denoted by the name becomes
+   the /iteratable object for the loop/. The default iterator function
+   for the type of the iteratable object for the loop is called on the
+   iteratable object and the result is the /loop iterator/. An object
+   of the default cursor subtype is created (the /loop cursor/).
+
+   If the reserved word REVERSE does not appear (does appear), then the
+   operation First (Last) of the (reversible) iterator type is called on
+   the loop iterator, to produce the initial value for the loop cursor.
+   If the initial value is equal to No_Element, then the execution of
+   the loop_statement is complete. Otherwise, the
+   sequence_of_statements is executed with the loop parameter denoting
+   an indexing (see 4.1.6) into the iteratable object for the loop, with
+   the only parameter to the indexing being the current value of the
+   loop cursor; then the Next (Previous) operation of the (reversible)
+   iterator type is called with the loop iterator and the loop cursor to
+   produce the next value to be assigned to the loop cursor. This
+   repeats until the loop cursor is equal to No_Element, or until the
+   loop is left as a consequence of a transfer of control. If the loop
+   parameter is a constant (see above), then the indexing uses the
+   default constant indexing function for the type of the iteratable
+   object for the loop; otherwise it uses the default variable indexing
+   function.
+
+
+
 !discussion [NOT FULLY UPDATED -- SEE PROPOSAL FOR SOME NEWER DISCUSSION]
 
 This is based on the earlier proposal and discussion recorded in AC-0112.TXT.
@@ -3385,6 +3751,91 @@
 changes specified in the minutes.  I will work on the wording for the actual ARG
 meeting.  The !proposal section might be worth reviewing in the upcoming ARG
 subgroup phone call.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, June 10, 2010  11:58 PM
+
+OK folks, this is a doozy.  I have produced some wording for the user-defined
+references, indexing, and iterators.  The references and the indexing were
+pretty straightforward.  Things got pretty hairy when I got to the iterators,
+because there were three different forms we were introducing, each with its own
+peculiarities.  I think I have the rules right, but the presentation might
+benefit from some restructuring. [This is version /06 of the AI - Editor.]
+
+So hopefully this is enough for us to look into the correctness and completeness
+of the wording at the ARG meeting.  We can then think about how better to
+present it.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Saturday, June 12, 2010  7:57 PM
+
+> OK folks, this is a doozy.
+
+You are right about that! A few comments noticed while posting this AI:
+
+In 4.1.6, you say "The aspects may not be overridden, but the functions they
+denote may be." I assume this is intended to be a Legality Rule (it's in
+introductory text, so I'm not sure how it is enforced).
+
+I think the reason you have this rule is so that indexing works on objects of
+T'Class: that requires dispatching and that means that the tag slot can't change
+for the indexing functions.
+
+However, this appears to be a generic contract model problem. We don't know
+whether or not these aspects were used when deriving from a generic formal, so
+it's not clear how the following works:
+
+    generic
+       type T is tagged private;
+    package Gen is
+       type NT is new T with private with
+           Variable_Indexing => Vfoo,
+           Constant_Indexing => Cfoo;
+       -- Assume definitions of Vfoo and Cfoo here.
+    end Gen;
+
+Is this specification legal? If Gen is instantiated with a type that has
+indexing already (such as Ada.Containers.Vectors), is the instance illegal? Etc.
+
+---
+
+You've defined an indexable type as a user-defined tagged type with the aspects
+specified. Are we allowing these to be specified on abstract types and
+interfaces? Those are user-defined tagged types. I can see reasons for allowing
+that, but we then have to be careful that we don't call abstract routines. (That
+also adds additional cases to the generic above.)
+
+---
+
+And why do you say "user-defined" in the indexable type definition? That seems
+to imply that the containers cannot be indexable, because they are defined by
+us, not the user. Clearly that is not what you meant, but why do we care who
+defined the type??
+
+---
+
+5.5.1:
+
+I'm not a fan of  "A /(reversible) iterator object/ is an object of a
+(reversible) iterator type." I was initially confused as to why you didn't
+define a "forward iterator object". But I eventually realized that you were
+being cute and are actually defining two terms with one sentence. I suppose the
+index will help a bit, but I suspect that many readers looking up "iterator
+object" will fail to see the definition here.
+
+---
+
+The legality rules for an iterable type seem to make the intended definition for
+Maps conflict with the rules for a default iterator. Specifically, I was
+expecting that we would define two pairs of indexing functions: one for cursors
+and the other for the key type, so that AI_Author_Map ("Taft") := 139; would be
+legal. But these rules only allow one index function. Shouldn't the rules be
+more flexible than that? Probably they should require the existence of an
+indexable function with the right profile, but allow the existence of others.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent