Version 1.6 of ai12s/ai12-0156-1.txt

Unformatted version of ai12s/ai12-0156-1.txt version 1.6
Other versions for file ai12s/ai12-0156-1.txt

!standard 5.5.2(2/3)          15-10-09 AI05-0156-1/02
!standard 5.5.2(5/4)
!standard 5.5.2(7/3)
!standard 3.10.2(11.1/2)
!class Amendment 15-02-26
!status work item 15-02-26
!status received 15-02-13
!priority Medium
!difficulty Easy
!subject Use subtype_indication in generalized iterators
An anonymous access declaration can be specified in an array component iterator if necessary to match the component subtype.
An optional subtype_indication can be provided with a generalized iterator.
One of the important features of Ada is that in almost all cases, the type of an object appears at the place where the object is declared. Thus it is not necessary to follow chains of declaration to find the type and subtype of an object.
Traditional for loops are the exception to this feature, as the type of I does not appear in "for I in 1 .. 10 loop". Here, however, the type is assumed, and Ada programmers quickly get used to that.
The reason for allowing the loop parameter to be specified for array component iterators and for component element iterators is to preserve this principle (at least optionally). Traditional for loops did not need such an option because the subtype is drawn directly from the given subtype_indication - the only thing that is missing is the colon.
However, there are two holes in this support:
(1) The syntax for array component iterators is:
defining_identifier [: subtype_indication] of [reverse] iterable_name
However, the syntax for the definition of the component subtype of an array type includes access_definition. Given our zeal for allowing anonymous access everywhere, it's odd that we're not allowing it here. As noted above, it's valuable that every declaration have its type easily determinable. And we already have rules to allow different anonymous access types to statically match, so there is no problem with allowing anonymous access here.
(2) The name of the cursor subtype does not appear anywhere in a generalized iterator. Again, a search through a chain of declarations is needed to find the name of this subtype (it will be found as the actual subtype in the instantiation of Ada.Iterator_Interfaces, so a minimum of three searches will be needed).
In order to be consistent with the other new kinds of iterators, we need to allow specifying the subtype in the case of a generalized iterator.
(See Summary.)
Replace 5.5.2(2/3) with: (Note: square and curly brackets as in syntax, not
wording modifications)
iterator_specification ::= defining_identifier [: loop_parameter_subtype_indication] in [reverse] iterator_name | defining_identifier [: loop_parameter_subtype_indication] of [reverse] iterable_name loop_parameter_subtype_indication ::= subtype_indication | access_definition
Add to the start of 5.5.2(5/4):
The subtype defined by the subtype_indication, if any, of a generalized iterator component iterator shall statically match the iteration cursor subtype.
Modify 5.5.2(7/3) by swapping the second and third sentences and making the other changes indicated:
An iterator_specification declares a loop parameter. In {a generalized iterator, }an array component iterator{,} or a container element iterator, if a {loop_parameter_}subtype_indication is present, it determines the nominal subtype of the loop parameter. In a generalized iterator, {if a loop_parameter_subtype_indication is not present, }the nominal subtype of the loop parameter is the iteration cursor subtype. In an array component iterator, if a {loop_parameter_}subtype_indication is not present, the nominal subtype of the loop parameter is the component subtype of the type of the iterable_name. In a container element iterator, if a {loop_parameter_}subtype_indication is not present, the nominal subtype of the loop parameter is the default element subtype for the type of the iterable_name.
Replace AARM 5.5.2(8.a/4) with:
The loop parameter of a generalized iterator has the same accessibility as the loop statement. This means that the loop parameter object is finalized when the loop statement is left. (It also may be finalized as part of assigning a new value to the loop parameter.) For array component iterators, the loop parameter directly denotes an element of the array and has the accessibility of the associated array. For container element iterators, the loop parameter denotes the result of the indexing function call (in the case of a constant indexing) or a generalized reference thereof (in the case of a variable indexing). Roughly speaking, the loop parameter has the accessibility level of a single iteration of the loop. More precisely, the function result (or the generalized reference thereof) is considered to be renamed in the declarative part of a notional block statement which immediately encloses the loop's sequence_of_statements; the accessibility of the loop parameter is that of the block statement.
And add after 3.10.2(11.1/2) as another bulleted list item
The accessibility level of an anonymous access type defined by an access_definition of a loop_parameter_subtype_indication is that of the loop parameter.
For hole 1, we allow anonymous access types for consistency with other kinds of object declaration (including extended return statements and generic formal parameters), and with the syntax for component declarations. Whether we should have done that for object declarations and component declarations can be argued, but since we have, there should not be places where anonymous access types cannot be written. Notice that static matching will always fail for container element iterators, as the Iterator_Element has to be a "name", and that does not include anonymous access types.
We've revised the accessibility rules to cover these anonymous access types. We also revised the note describing the accessibility of loop parameters to properly explain the container element iterator case, as the old description seemed to require the nonsense of keeping the results of the indexing function calls until the loop exited (as opposed to just the end of the iteration).
For hole 2, we allow an optional subtype_indication on a generalized iterator. We don't want to force readers to look through many declarations to find out the type of a loop parameter. We allow that type to be optional, however, as it often is obvious from context. For instance, if one is iterating a language-defined container, everyone should know that the cursor type is named Cursor and it's defined in the instance that defines the container type. But that's not true for user-defined iterators, which may have been added to existing types for which the name "Cursor" is not appropriate.
We don't need to allow an access_definition in a generalized iterator, as the actual type provided to any generic instance (including an instance of Ada.Iterator_Interfaces) is a subtype_mark; it cannot be an anonymous access_definition. We use loop_parameter_subtype_indication anyway, just to simplify the wording.
We could have allowed an optional subtype_indication in a traditional for loop as well. But "in" here acts much like ":", so we don't really need the extra subtype. And the static matching requirement would mean that the same subtype would have to be written twice in most circumstances:
for I : Short in Short loop
A charter member of the department of redundancy department. In addition, it would have required additional wording and syntax changes in subclause 5.5. So this does not seem worthwhile.
No ASIS effect.
!ACATS test
An ACATS C-Test is needed to check that the new capabilities are supported.

This AI was split from AI12-0151-1 by the February 26th, 2015 ARG phone
meeting. To find the initial e-mail discussion, check that AI.


Questions? Ask the ACAA Technical Agent