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

Differences between 1.8 and version 1.9
Log of other versions for file ai12s/ai12-0262-1.txt

--- ai12s/ai12-0262-1.txt	2019/01/16 03:16:49	1.8
+++ ai12s/ai12-0262-1.txt	2019/01/18 06:20:07	1.9
@@ -1,9 +1,10 @@
-!standard 4.1.4(1)                                    19-01-14  AI12-0262-1/06
+!standard 4.1.4(1)                                    19-01-17  AI12-0262-1/08
 !standard 4.1.4(6)
 !standard 4.1.4(11)
-!standard 4.5.9(0)
+!standard 4.5.10(0)
 !class Amendment 18-03-01
 !status Amendment 1-2012 19-01-15
+!status work item 19-01-17
 !status ARG Approved 9-0-2  19-01-14
 !status work item 18-03-01
 !status received 18-03-01
@@ -189,18 +190,18 @@
 The evaluation of a range_attribute_reference or an attribute_reference that
 is not a reduction_attribute_reference consists of the evaluation of the 
 prefix. Redundant[The evaluation of a reduction_attribute_reference is defined 
-in 4.5.9.]
+in 4.5.10.]
 
 
-New Section 4.5.9
+New Section 4.5.10
 
-4.5.9 Reduction Expressions
+4.5.10 Reduction Expressions
 
-Reduction expressions provides a way to map or transform a collection of
+Reduction expressions provide a way to map or transform a collection of
 values into a new set of values, and then summarize the values produced by
 applying an operation to reduce the set to a single value result.
-A reduction expression is represented as an attribute_reference using the 
-Reduce attribute.
+A reduction expression is represented as an attribute_reference of the 
+reduction attribute Reduce.
 
 Syntax
 
@@ -212,46 +213,73 @@
 
 reduction_specification ::= /reducer_/name, /initial_value_/expression[, /combiner_/name]
 
+  For the case of an iterated_component_association of a value_sequence
+  having a discrete_choice_list, there shall be exactly one
+  discrete_choice in the discrete_choice_list, which shall be
+  a discrete_subtype_indication or a range.
+  
+    AARM Reason: If we allow multiple choices, we would have a new
+    overload resolution challenge, where you could have multiple
+    ranges requiring resolution across them. We disallow single values
+    because that would be useless, and we disallow "others" because there 
+    is no applicable index constraint. The user can use a qualified 
+    expression if they really need to use the full flexibility of 
+    array-aggregate notation.
+
+    AARM Ramification: There is no rule against discrete_choice_list of a 
+    value_sequence having a discrete_choice that is a subtype_indication or 
+    range that defines a nonstatic or null range. If the choice is a 
+    subtype_indication, the denoted subtype may have a static or
+    dynamic predicate.
 
 Name Resolution Rules
 
 The expected type for a reduction_attribute_reference shall be a single
 nonlimited type.
+
+Given nonlimited subtypes Val_Type and Acc_Type, where Acc_Type is a subtype 
+of the expected type of the reduction_attribute_reference:
 
-Given nonlimited subtypes I and R, where R is a subtype of the expected type
-of the reduction_attribute_reference:
+   AARM Discussion: Acc_Type is short for accumulator type (the result of the
+   reduction), and Val_Type is short for value type (the type of the input
+   values to the reduction).
 
 A /reducer_/subprogram is either subtype conformant with the following
 specification:
 
-   function Reducer(Accumulator : R; Value : I) return R;
+   function Reducer(Accumulator : Acc_Type; Value : Val_Type) return Acc_Type;
 
 or is subtype conformant with the following specification:
 
-   procedure Reducer(Accumulator : in out R; Value : I);
+   procedure Reducer(Accumulator : in out Acc_Type; Value : Val_Type);
 
-A /combiner_/subprogram is a /reducer_/subprogram where subtypes I and R
-statically match.
+A /combiner_/subprogram is a /reducer_/subprogram where both parameters are 
+of subtype Acc_Type.
 
 The reducer_name of a reduction_specification denotes a reducer_subprogram.
 
 The combiner_name of a reduction_specification denotes a combiner_subprogram.
 
 The expected type of an initial_value_expression of a reduction_specification
-is that of subtype R.
+is that of subtype Acc_Type.
 
 The expected type of the expression of a value_sequence is that of
-subtype I.
+subtype Val_Type.
 
-The expected type of the index parameter of a value_sequence is that of the
-discrete_choice. The expected type of the loop parameter of a value_sequence 
-is as defined for an iterator_specification (see 5.5.2).
-
-The expected type for a value_sequence shall be a single one-dimensional array
-type. The component type of this array type is the expected type of the index
-parameter or loop parameter for the value_sequence.
+For an iterated_component_association of a value_sequence that has a 
+discrete_choice_list comprising a single range, the range shall resolve to 
+some discrete type[Redundant:; which discrete type shall be determined without 
+using any context other than the bounds of the range itself (plus the 
+preference for root_integer  see 8.6).].  If the range resolves to 
+/root_integer/; the type of the index parameter of the 
+iterated_component_association (the /index type/ of the value_sequence) is 
+Integer; otherwise the index type is the resolved type of the 
+discrete_subtype_indication or range of the discrete_choice_list. For an 
+iterated_component_assocation of a value_sequence that has an 
+iterator_specification, the /index type/ of the value_sequence is Integer 
+[Redundant: and the type of the loop parameter of the iterator_specification 
+is as defined in 5.2.2].
 
-
 Legality Rules
 
 The combiner_name of a reduction_specification shall be specified
@@ -267,15 +295,6 @@
 is no need to provide a way to combine multiple results.
 End AARM Reason.
 
-The discrete_choice_list of a value_sequence shall have a single discrete_choice
-and the discrete_choice shall not be the reserved word others.
-
-AARM Ramification: The discrete_choice_list of a value_sequence may have a 
-discrete_choice that is a nonstatic choice_expression or that is a 
-subtype_indication or range that defines a nonstatic or null range. If the
-choice is a subtype_indication, the denoted subtype may have a static or
-dynamic predicate.
-
 Static Semantics
 
 The nominal subtype of the index parameter of a value_sequence
@@ -293,55 +312,81 @@
 
 Dynamic Semantics
 
-For a reduction_attribute_reference, first the value_sequence is first evaluated.
-For a value_sequence with or without the reserved word parallel, the evaluation
-of a value_sequence is as defined for an array aggregate (see 4.3.3).
-The reduction_attribute_designator is then evaluated, and then the reduction is 
-evaluated.
+For the evaluation of a value_sequence, the evaluation proceeds as for a 
+single-dimensional array aggregate (see 4.3.3) with component type being 
+Val_Type and with index type as defined above, with the sequence of values 
+of the value_sequence corresponding to the components of the 
+notional array so defined, in increasing index order.
 
 AARM Discussion:
 The presence of the parallel keyword does not effect the evaluation of
-the value_sequence. Conceptually, an array aggregate is produced, as though
-the parallel keyword were not present.
+the value_sequence. Conceptually, a sequential sequence of values is produced,
+as though the parallel keyword were not present.
 
 AARM Implementation Note:
 The intended implementation model is that a value_sequence generally avoids
-producing a temporary array aggregate object, and instead issue calls to
-the Reducer as values are produced by the evaluation of the value_sequence.
+producing a temporary object, and instead issue calls to the Reducer as values
+are produced by the evaluation of the value_sequence.
 
 The following attribute is defined for a value_sequence V:
-
-V'Reduce(Reducer, Initial_Value[, Combiner])
 
-   V'Reduce evaluates the Initial_Value,
-   then initializes the result of the reduction expression to the value
-   of the Initial_Value expression. If the value_sequence does not have
-   the reserved word parallel, the value of each component of the array
-   aggregate produced by the value_sequence is passed in ascending order as the
-   second (Value) parameter to execute a call to Reducer, using the result of
-   the previous iteration as the first (Accumulator) parameter of the call.
-   The result of V'Reduce is the final result of the iteration. If the 
-   reserved word parallel is present in a value_sequence (a parallel 
-   reduction), then the reduction expression is a parallel construct and the 
-   iterations are partitioned into one or more chunks, each with its own 
-   separate logical thread of control (see clause 9). Each logical thread of 
-   control generates a local copy of the result of its iteration, which is 
-   initialized to the value of the expression produced by the first assigned 
-   iteration. As each logical thread of control completes its assigned 
-   iterations, the Combiner is called using the value of the local result as 
-   the second (Value) parameter of the call, and using the previous final 
-   result value, as the the first (Accumulator) parameter for the call. Once 
-   all logical threads of control have completed, V'Reduce yields the result
-   of the last call to Combiner. The calls to Combiner are executed in
-   increasing iteration order. The Combiner may be omitted if the Reducer is
-   also a combiner_subprogram. In that case, the Reducer is implicitly used
-   also as the Combiner argument.
+V'Reduce (/reducer_/name, /initial_value_/expression[, /combiner_/name])
 
-   If the value_sequence of the reduction_attribute reference produces an
-   empty sequence, V'Reduce yields the value of the Initial_Value expression 
+   The evaluation of a use of this attribute (a /reduction expression/)
+   begins by evaluating the value_sequence V, the /reducer_/name, the
+   /initial_value_/expression, and the /combiner_/name (if any), in any
+   order. It then initializes the /accumulator/ of the reduction
+   expression to the value of the /initial_value_/expression (the
+   /initial value/). 
+
+   If the value_sequence does not have the reserved word parallel, each
+   value of the value_sequence is passed, in order, as the second
+   (Value) parameter to a call on the reducer, with the first
+   (Accumulator) parameter being the prior value of the accumulator,
+   saving the result as the new value of the accumulator. The reduction
+   expression yields the final value of the accumulator.  The
+   /combiner_/name, if specified, is ignored for such a (sequential)
+   reduction expression.
+
+   If the reserved word parallel is present in a value_sequence, then
+   the (parallel) reduction expression is a parallel construct and the
+   sequence of values is partitioned into one or more contiguous
+   non-empty chunks (/subsequences/), each with its own separate logical
+   thread of control (see clause 9). Each logical thread of control
+   creates a local accumulator for processing its subsequence.  If there
+   is a separate combiner subprogram specified, then the accumulator for
+   each subsequence is initialized to the initial value, and the reducer
+   is called in sequence order with each value of the subsequence as the
+   second (Value) parameter, and with this local accumulator as the
+   first (Accumulator) parameter, saving the result back into this local
+   accumulator.  If there is no separate combiner specified, then the
+   accumulator for a subsequence is initialized to the first value of
+   the subsequence, and calls on the reducer start with the second value
+   of the subsequence (if any).  In either case, the result for the
+   subsequence is the final value of its local accumulator.  
+   
+   After all logical threads of control of a parallel reduction
+   expression have completed, the combiner is called for each
+   subsequence, in the original sequence order, passing the local
+   accumulator for that subsequence as the second (Value) parameter, and
+   the overall accumulator [Redundant: (initialized above to the initial
+   value)] as the first (Accumulator) parameter, with the result saved
+   back in the overall accumulator. The parallel reduction expression
+   yields the final value of the overall accumulator.
+
+   For a parallel reduction expression, the /combiner_/name may be
+   omitted if the reducer is also a combiner_subprogram. In that case,
+   the reducer subprogram is implicitly used as the combiner.
+
+   If the evaluation of the value_sequence yields an empty sequence of
+   values, the reduction expression yields the initial value.
+   
+   If an exception is propagated by one of the calls on the reducer or
+   combiner subprogram, that exception is propagated from the
+   reduction expression.  If different exceptions are propagated in
+   different logical threads of control, one is chosen arbitrarily to be
+   propagated from the reduction expression as a whole.
 
-
-
 AARM Implementation Note:
 For a reduction_attribute_reference that has a value_sequence without the 
 parallel keyword, generally the compiler can still choose to execute the 
@@ -365,13 +410,32 @@
 synchronization if the calls to Combiner are being executed by different 
 logical threads of control.
 
-NOTES
+Bounded Errors
 
-The Initial_Value of a reduction expression is only evaluated once.
+  If a parallel reduction expression has a combiner subprogram
+  specified, then it is a bounded error if the initial value is not the
+  (left) identity of the combiner subprogram. That is, the result of
+  calling the combiner subprogram with the Accumulator being the initial
+  value and the Value being any arbitrary value of subtype Acc_Type should
+  produce a result equal to the Value parameter. The possible consequences
+  are Program_Error, or a result that does not match the equivalent
+  sequential reduction expression due to multiple uses of the
+  non-identity initial value in the overall reduction.
+  
+    AARM Reason: There is no way to do the individual subsequence
+    reductions when the Acc_Type and the Val_Type are not the same,
+    unless we can initialize the local accumulator with an initial-value
+    that is presumed to be the identity. If the initial value is not
+    the identity, and there is more than one chunk, it will be included
+    more than once in the overall reduction. We associate this bounded
+    error with there being a combiner subprogram specified, since that
+    is necessary only when Acc_Type and Val_Type are different, and
+    because the dynamic semantics above specify the use of the initial
+    value multiple times whenever a combiner is specified. We chose to
+    base the dynamic semantics rules on the presence of a separate
+    combiner, rather than on the matching between Acc_Type and Val_Type,
+    since the presence of the combiner is more visible in the source.
 
-The /reducer_/subprogram and the /combiner_/subprogram /potentially conflict/
-with other actions.
-
 Examples
 
   --  Determine how many integers in an array are prime numbers
@@ -1054,5 +1118,626 @@
 That's it for the !wording. Note that I didn't try to figure out if this does 
 the right thing (I barely know what that is :-), but just that the wording 
 organization made sense.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, January 15, 2019  10:22 PM
+
+Under Name Resolution Rules for AI12-0262-1, we have the following rule:
+
+  The expected type for a value_sequence shall be a single one-dimensional 
+  array type. The component type of this array type is the expected type of 
+  the index parameter or loop parameter for the value_sequence.
+
+This cannot be what we want. As written, this requires an actual type 
+somewhere in the program's universe with these characteristics. Moreover, 
+we wanted to allow cases where an actual array could not be declared (the 
+component type being indefinite, such as T'Class). This rule doesn't allow 
+that.
+
+Probably what Brad (or someone) was thinking is that we need a nominal array 
+type so that we can reuse the array aggregate dynamic semantics for describing
+how a value_sequence is evaluated. But we don't want to describe that as a 
+"Name Resolution Rule".
+
+(Side note: The description above is wrong, too: the component type needs to 
+be "I", the type of the value being reduced. It doesn't have anything to do 
+with the index/loop parameter.)
+
+I think it probably would be best to simply define this imaginary array type 
+in the one place that it matters, and that is the Dynamic Semantics. The only
+problem is the "I", the type of the component, is defined a long ways away. It
+probably would be better if "I" and "R" had real names. Maybe "reduction 
+component type" and "reduction result type"???
+
+Anyway, we need a rule at the top of the Dynamic Semantics section to give 
+this phony array definition:
+
+  For the purposes of evaluation of a reduction expression, a value_sequence 
+  is presumed to be of a one-dimensional array type with a component type of 
+  I (<better name here>). The index subtype is that of the discrete_range if 
+  present, and Standard.Integer otherwise.
+
+AARM Discussion: We use this type only for purposes of describing the 
+evaluation of the value_sequence. There does not need to be any type with 
+these characteristics available in the program. Indeed, if I is an indefinite 
+type, one cannot even declare such a type.
+
+AARM To Be Honest: The index subtype is chosen to avoid any check failures.
+But there is no intent to check that the aggregate determined would fit in 
+the index subtype; that might matter on a system with Integer'Last = 2**15-1.
+
+We might want to consider splitting up the current the first paragraph to 
+include this information in the wording for evaluating the value_sequence, 
+rather than putting it before everything else.
+
+Anyway, does this make sense? Are there any better ideas of how to define the 
+evaluation of the value_sequence? (doing that exclusively here seems 
+unappealing, as a number of rules would have to be copied).
+
+P.S. I suggest fixing this in a clean-up AI. Have no interest in reopening 
+this AI. :-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 16, 2019  1:01 PM
+
+> Under Name Resolution Rules for AI12-0262-1, we have the following rule:
+> 
+>  The expected type for a value_sequence shall be a single 
+> one-dimensional array  type. The component type of this array type is 
+> the expected type of the index  parameter or loop parameter for the 
+> value_sequence.
+> 
+> This cannot be what we want. As written, this requires an actual type 
+> somewhere in the program's universe with these characteristics. 
+> Moreover, we wanted to allow cases where an actual array could not be 
+> declared (the component type being indefinite, such as T'Class). This 
+> rule doesn't allow that.
+
+Good point.  One of the whole goals of the reduction expression is to do a 
+reduction without ever "actualizing" such an array, and without having to 
+declare such an array type.  A value sequence doesn't have a type, or if it
+does, it is an anonymous array type.
+ 
+> Probably what Brad (or someone) was thinking is that we need a nominal 
+> array type so that we can reuse the array aggregate dynamic semantics 
+> for describing how a value_sequence is evaluated. But we don't want to 
+> describe that as a "Name Resolution Rule".
+> 
+> (Side note: The description above is wrong, too: the component type 
+> needs to be "I", the type of the value being reduced. It doesn't have 
+> anything to do with the index/loop parameter.)
+> 
+> I think it probably would be best to simply define this imaginary 
+> array type in the one place that it matters, and that is the Dynamic 
+> Semantics. The only problem is the "I", the type of the component, is 
+> defined a long ways away. It probably would be better if "I" and "R" 
+> had real names. Maybe "reduction component type" and "reduction result 
+> type"???
+> 
+> Anyway, we need a rule at the top of the Dynamic Semantics section to 
+> give this phony array definition:
+> 
+>     For the purposes of evaluation of a reduction expression, a 
+> value_sequence is presumed to be of a one-dimensional array type with 
+> a component type of I (<better name here>). The index subtype is that 
+> of the discrete_range if present, and Standard.Integer otherwise.
+> 
+> AARM Discussion: We use this type only for purposes of describing the 
+> evaluation of the value_sequence. There does not need to be any type 
+> with these characteristics available in the program. Indeed, if I is 
+> an indefinite type, one cannot even declare such a type.
+> 
+> AARM To Be Honest: The index subtype is chosen to avoid any check failures.
+> But there is no intent to check that the aggregate determined would 
+> fit in the index subtype; that might matter on a system with 
+> Integer'Last = 2**15-1.
+> 
+> We might want to consider splitting up the current the first paragraph 
+> to include this information in the wording for evaluating the 
+> value_sequence, rather than putting it before everything else.
+> 
+> Anyway, does this make sense? Are there any better ideas of how to 
+> define the evaluation of the value_sequence? (doing that exclusively 
+> here seems unappealing, as a number of rules would have to be copied).
+
+This seems like a lot of horsing around for no clear reason.  I suggest we 
+adjust the wording a bit so we don't need to talk about this array type at 
+all.  Let me give it a shot.  (I'll try to send something shortly.)
+
+> P.S. I suggest fixing this in a clean-up AI. Have no interest in 
+> reopening this AI. :-)
+
+Agreed.
+
+I also noticed a problem with the "NOTES" at the bottom:
+
+* The Initial_Value of a reduction expression is only evaluated once.
+* The /reducer_/subprogram and the /combiner_/subprogram /potentially 
+  conflict/ with other actions.
+
+The first bullet has a number of problems, and might be best eliminated.  
+But if we wanted to get it exactly right:
+* The evaluation of a reduction expression includes exactly one evaluation of 
+  the Initial_Value expression.
+
+The second bullet is very confusing, as it is "actions", not "subprograms," 
+that potentially conflict.  If it is non-normative, I suggest we remove it, 
+as it would be more confusing than clarifying for most users, I would guess. 
+If it is normative, it doesn't belong in a NOTE.  But I hope it is implied by
+the dynamic semantics, and so should probably just be dropped.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, January 16, 2019  1:30 PM
+
+> One of the whole goals of the reduction expression is to do a reduction 
+> without ever "actualizing" such an array, and without having to declare 
+> such an array type.  A value sequence doesn't have a type, or if it does,
+> it is an anonymous array type.
+
+If we want to preserve the wording (and perhaps we don't) defining the 
+dynamic semantics of evaluating a sequence in terms of evaluation of an 
+array aggregate, then it seems like we need some notional anonymous array 
+type. In particular, the component subtype of this notional array type would 
+need to be defined and, unlike "real" array types, that subtype might be 
+indefinite (e.g., for the case where the value sequence is a sequence of 
+values of a class-wide type, or where it is a sequence of array values having 
+differing lengths).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 16, 2019  1:57 PM
+
+Right. Defining a notional array type is what I was trying to do with my 
+suggested wording. Otherwise, we'd have to define the semantics of evaluating 
+the value sequence here, and stop describing it as an array aggregate (which 
+happens in a variety of places). That in fact would be my preference if it 
+is short enough, but that's a large IF.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Wednesday, January 16, 2019  2:08 PM
+
+Now that we have container aggregates, it might be simpler to relate the 
+sequence to the construction of a list container, so the index is unrelated
+to any index type of that notional anonymous array type.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 16, 2019  5:12 PM
+
+The proposed dynamic semantics for parallel reduction don't seem to work if 
+the value type ("I") and the accumulator type ("R") are different:
+
+   "... If the reserved word parallel is
+   present in a value_sequence (a parallel reduction), then the reduction
+   expression is a parallel construct and the iterations are partitioned into
+   one or more chunks, each with its own separate logical thread of control (see
+   clause 9). Each logical thread of control generates a local copy of the
+   result of its iteration, which is initialized to the value of the expression
+   produced by the first assigned iteration."
+
+Some of this terminology I believe could be improved, but in any case, the 
+"first assigned iteration" is the first value in the chunk of values assigned 
+to the logical thread of control, and that is of the "value" type ("I").  But 
+the final result of a reduction expression is supposed to be of the 
+"accumulator" type ("R").  So this doesn't work as written.  I think we need 
+to use the value of the initial-value expression even in a parallel reduction,
+since that has the right type (namely, the accumulator type).  I realize there
+are some down sides to that, since it means the initial value really needs to
+be the identity of the reduction, so we need to make that very clear.  For the
+sequential reduction, the initial value can be arbitrary.
+
+Note that if the two parameter subtypes to the reducer are the same, then the 
+above description works OK (i.e. accumulator and value types are the same).  
+We could say that if there is a combiner specified for a parallel reduction, 
+then the initial-value expression needs to be the identity of the reducer (and 
+the combiner, presumably!).  If no combiner is specified, the initial-value 
+need not be an identity of the reducer, since we can use the "trick" used 
+above, where the first value of each chunk is the starting value for the 
+accumulator.  But again, this only works if the values and the accumulator(s) 
+are of the same type.  
+
+Note that in this latter case, it is important that the initial-value 
+expression *is* used in the final sequence of calls combining all of the 
+individual chunk accumulators into the final result.
+
+Unless someone objects, I'll go with this last idea in my "fixup" work on 
+this AI, where if there is a separate combiner specified, we make it a 
+bounded error if the initial-value is not an identity for both reducer and 
+combiner.  If there is no combiner specified, then the initial-value will be
+included in the overall reduction exactly once, just as it is in the 
+sequential reduction.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 16, 2019  5:41 PM
+
+> The proposed dynamic semantics for parallel reduction don't seem to 
+> work if the value type ("I") and the accumulator type
+> ("R") are different:
+
+I think I follow your argument, and it makes sense to me.
+
+BTW, can we give these types real names? I and R don't make a lot of sense 
+in rules a page down from the definition. "Value type" and "accumulator 
+type" also help motivate what is going on.
+
+****************************************************************
+
+From: Brad Moore
+Sent: Wednesday, January 16, 2019  8:04 PM
+
+> Unless someone objects, I'll go with this last idea in my "fixup" work 
+> on this AI, where if there is a separate combiner specified, we make 
+> it a bounded error if the initial-value is not an identity for both 
+> reducer and combiner.  If there is no combiner specified, then the 
+> initial-value will be included in the overall reduction exactly once, 
+> just as it is in the sequential reduction.
+
+Agreed, with all you have said... 
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 16, 2019  7:39 PM
+
+Here is an attempt to address the problems identified earlier, as well as 
+several others that Randy and others have noticed.  I purposely did *not* 
+introduce the chunk-specification syntax into this, as I believe we agreed
+that that will be a separate AI.  I made the last-minute switch from "I" and
+"R" to "Val_Type" and "Acc_Type" as suggested in this e-mail from Randy.
+
+> BTW, can we give these types real names? I and R don't make a lot of 
+> sense in rules a page down from the definition. "Value type" and 
+> "accumulator type" also help motivate what is going on.
+
+---------
+
+Fixups for AI12-0262-1 on reduction expressions
+
+[These were used to create version /08 of the AI - Editor.]
+
+Modify the introduction, as follows:
+
+Reduction expressions provide[s] a way to map or transform a collection of 
+values into a new set of values, and then summarize the values produced by 
+applying an operation to reduce the set to a single [value] result.  {A 
+reduction expression is represented as a reference to the reduction 
+attribute Reduce.}
+
+-------
+
+Add the following immediately after the BNF (within the Syntax Rules section):
+
+  For the case of an iterated_component_association of a value_sequence
+  having a discrete_choice_list, there shall be exactly one
+  discrete_choice in the discrete_choice_list, which shall be
+  a discrete_subtype_indication or a range.
+  
+    AARM Reason: If we allow multiple choices, we would have a new
+    overload resolution challenge, where you could have multiple
+    ranges requiring resolution across them.  We disallow single values
+    because that would be weird, and we disallow "others" because
+    there is no applicable index constraint.  The user can use a
+    qualified expression if they really need to use the full flexibility
+    of array-aggregate notation.
+    
+---
+  
+Name Resolution
+
+Change "R" and "I" to "Acc_Type" and "Val_Type" throughout (based on a 
+suggestion by Randy).
+
+...
+
+Modify the following paragraph, as follows:
+
+A /combiner_/subprogram is a /reducer_/subprogram where [subtypes I and R 
+statically match] {both parameters are of subtype Acc_Type}.
+
+...
+
+Replace the last two paragraphs of Name Resolution, which are currently:
+
+The expected type of the index parameter of a value_sequence is that of the 
+discrete_choice. Otherwise, the expected type of the loop parameter of a 
+value_sequence is as defined for an iterator_specification (see 5.5.2).
+
+The expected type for a value_sequence shall be a single one-dimensional 
+array type. The component type of this array type is the expected type of the 
+index parameter or loop parameter for the value_sequence.
+
+with:
+
+For an iterated_component_association of a value_sequence that has a 
+discrete_choice_list comprising a single range, the range shall resolve to 
+some discrete type[Redundant:; which discrete type shall be determined without 
+using any context other than the bounds of the range itself (plus the 
+preference for root_integer  see 8.6).].  If the range resolves to 
+/root_integer/; the type of the index parameter of the 
+iterated_component_association (the /index type/ of the value_sequence) is 
+Integer; otherwise the index type is the resolved type of the 
+discrete_subtype_indication or range of the discrete_choice_list. For an 
+iterated_component_assocation of a value_sequence that has an 
+iterator_specification, the /index type/ of the value_sequence is Integer 
+[Redundant: and the type of the loop parameter of the 
+iterator_specification is as defined in 5.2.2].
+
+---
+
+Dynamic Semantics
+
+Replace the following:
+
+Dynamic Semantics
+
+For a reduction_attribute_reference, the value_sequence is first evaluated.
+For a value_sequence with or without the reserved word parallel, the 
+evaluation of a value_sequence is as defined for an array aggregate 
+(see 4.3.3). The reduction_attribute_designator is then evaluated.
+
+with:
+
+Dynamic Semantics
+
+For the evaluation of a value_sequence, the evaluation proceeds as for a 
+single-dimensional array aggregate (see 4.3.3) with component type being 
+Val_Type and with index type as defined above, with the sequence of values
+of the value_sequence corresponding to the components of the notional array
+so defined, in increasing index order.
+
+---
+
+Replace the paragraphs defining the V'Reduce attribute with the following:
+
+The following attribute is defined for a value_sequence V:
+
+V'Reduce (/reducer_/name, /initial_value_/expression[, /combiner_/name])
+
+   The evaluation of a use of this attribute (a /reduction expression/)
+   begins by evaluating the value_sequence V, the /reducer_/name, the
+   /initial_value_/expression, and the /combiner_/name (if any), in any
+   order. It then initializes the /accumulator/ of the reduction
+   expression to the value of the /initial_value_/expression (the
+   /initial value/). 
+
+   If the value_sequence does not have the reserved word parallel, each
+   value of the value_sequence is passed, in order, as the second
+   (Value) parameter to a call on the reducer, with the first
+   (Accumulator) parameter being the prior value of the accumulator,
+   saving the result as the new value of the accumulator. The reduction
+   expression yields the final value of the accumulator.  The
+   /combiner_/name, if specified, is ignored for such a (sequential)
+   reduction expression.
+
+   If the reserved word parallel is present in a value_sequence, then
+   the (parallel) reduction expression is a parallel construct and the
+   sequence of values is partitioned into one or more contiguous
+   non-empty chunks (/subsequences/), each with its own separate logical
+   thread of control (see clause 9). Each logical thread of control
+   creates a local accumulator for processing its subsequence.  If there
+   is a separate combiner subprogram specified, then the accumulator for
+   each subsequence is initialized to the initial value, and the reducer
+   is called in sequence order with each value of the subsequence as the
+   second (Value) parameter, and with this local accumulator as the
+   first (Accumulator) parameter, saving the result back into this local
+   accumulator.  If there is no separate combiner specified, then the
+   accumulator for a subsequence is initialized to the first value of
+   the subsequence, and calls on the reducer start with the second value
+   of the subsequence (if any).  In either case, the result for the
+   subsequence is the final value of its local accumulator.  
+   
+   After all logical threads of control of a parallel reduction
+   expression have completed, the combiner is called for each
+   subsequence, in the original sequence order, passing the local
+   accumulator for that subsequence as the second (Value) parameter, and
+   the overall accumulator [Redundant: (initialized above to the initial
+   value)] as the first (Accumulator) parameter, with the result saved
+   back in the overall accumulator. The parallel reduction expression
+   yields the final value of the overall accumulator.
+
+   For a parallel reduction expression, the /combiner_/name may be
+   omitted if the reducer is also a combiner_subprogram. In that case,
+   the reducer subprogram is implicitly used as the combiner.
+
+   If the evaluation of the value_sequence yields an empty sequence of
+   values, the reduction expression yields the initial value.
+   
+   If an exception is propagated by one of the calls on the reducer or
+   combiner subprogram, that exception is propagated from the
+   reduction expression.  If different exceptions are propagated in
+   different logical threads of control, one is chosen arbitrarily to be
+   propagated from the reduction expression as a whole.
+   
+---
+
+Add the following:
+
+Bounded Errors
+
+  If a parallel reduction expression has a combiner subprogram
+  specified, then it is a bounded error if the initial value is not the
+  (left) identity of the combiner subprogram. That is, the result of
+  calling the combiner subprogram with the Accumulator being the initial
+  value and the Value being any arbitrary value of subtype Acc_Type should
+  produce a result equal to the Value parameter.  The possible consequences
+  are Program_Error, or a result that does not match the equivalent
+  sequential reduction expression due to multiple uses of the
+  non-identity initial value in the overall reduction.
+  
+    AARM Reason: There is no way to do the individual subsequence
+    reductions when the Acc_Type and the Val_Type are not the same,
+    unless we can initialize the local accumulator with an initial-value
+    that is presumed to be the identity.  If the initial value is not
+    the identity, and there is more than one chunk, it will be included
+    more than once in the overall reduction.  We associate this bounded
+    error with there being a combiner subprogram specified, since that
+    is necessary only when Acc_Type and Val_Type are different, and
+    because the dynamic semantics above specify the use of the initial
+    value multiple times whenever a combiner is specified.  We chose to
+    base the dynamic semantics rules on the presence of a separate
+    combiner, rather than on the matching between Acc_Type and Val_Type,
+    since the presence of the combiner is more visible in the source.
+
+---
+
+Delete the two NOTES as they have some wording issues, and are probably not 
+that helpful.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 17, 2019  12:15 AM
+
+> Here is an attempt to address the problems ...
+
+Thanks for doing this. When can I get your homework, similar wording changes 
+to AI12-0266-1? :-)
+
+> Modify the introduction, as follows:
+> 
+> Reduction expressions provide[s] a way to map or transform a 
+> collection of values into a new set of values, and then summarize the 
+> values produced by applying an operation to reduce the set to a single 
+> [value] result.  {A reduction expression is represented as a reference 
+> to the reduction attribute Reduce.}
+
+"reference" here strikes me as strange. Either is just a use of the attribute, 
+or it is an attribute_reference. I changed the text to use the latter, since 
+that was the change agreed upon during the meeting.
+
+I also note that this wording needs to be changed further to take AI12-0242-1 
+into account, which defines a Parallel_Reduce attribute.
+
+So, I ultimately used:
+A reduction expression is represented as an attribute_reference of the 
+reduction attributes Reduce or Parallel_Reduce.
+
+[For AI12-0262-1 individually, I dropped the Parallel_Reduce part.]
+
+>Add the following immediately after the BNF (within the Syntax Rules section):
+>
+>  For the case of an iterated_component_association of a value_sequence  
+> having a discrete_choice_list, there shall be exactly one  
+> discrete_choice in the discrete_choice_list, which shall be  a 
+> discrete_subtype_indication or a range.
+
+I presume you want to delete the Legality Rule that said essentially this.
+There's no point in having both. That forced me to move the AARM Note about
+dynamic choices to the Syntax section. It doesn't really belong there, but 
+it makes no sense floating in Legality Rules with no related text.
+
+>     AARM Reason: If we allow multiple choices, we would have a new
+>     overload resolution challenge, where you could have multiple
+>     ranges requiring resolution across them.  We disallow single values
+>     because that would be weird, and we disallow "others" because
+>     there is no applicable index constraint.  The user can use a
+>     qualified expression if they really need to use the full flexibility
+>     of array-aggregate notation.
+
+We can do better than "weird". I used "useless". I wanted to use "only useful 
+for an obfuscated code contest", 'cause I was thinking about:
+
+   [for I in 1 => I]'Reduce ("+", A)
+
+which is a really complicated way to add 1 to A. Of course, we still allow:
+ 
+   [for I in 0..1 => I]'Reduce ("+", A)
+
+which is an even more complicated way to add 1 to A. So I just settled on 
+"useless". :-)
+
+
+> ---
+>   
+> Name Resolution
+> 
+> Change "R" and "I" to "Acc_Type" and "Val_Type" throughout (based on a 
+> suggestion by Randy).
+
+I added a short AARM note to this:
+
+   AARM Discussion: Acc_Type is short for accumulator type (the result of the
+   reduction), and Val_Type is short for value type (the type of the input
+   values to the reduction).
+
+I could see making something like this NOTE, except that notes are all at the 
+bottom when its far too late for these to do any good.
+
+> ---
+> 
+> Dynamic Semantics
+> 
+> Replace the following:
+> 
+> Dynamic Semantics
+> 
+> For a reduction_attribute_reference, the value_sequence is first 
+> evaluated.
+> For a value_sequence with or without the reserved word parallel, the 
+> evaluation of a value_sequence is as defined for an array aggregate 
+> (see 4.3.3).
+> The reduction_attribute_designator is then evaluated.
+> 
+> with:
+> 
+> Dynamic Semantics
+> 
+> For the evaluation of a value_sequence, the evaluation proceeds as for 
+> a single-dimensional array aggregate (see
+> 4.3.3) with component type being Val_Type and with index type as 
+> defined above, with the sequence of values of the value_sequence 
+> corresponding to the components of the notional array so defined, in 
+> increasing index order.
+
+You didn't edit the following AARM notes. I tried to scrub the discussion 
+of "array aggregate" from them while leaving the gist. 
+
+AARM Discussion:
+The presence of the parallel keyword does not effect the evaluation of the 
+value_sequence. Conceptually, a sequential sequence of values is produced, 
+as though the parallel keyword were not present.
+
+AARM Implementation Note:
+The intended implementation model is that a value_sequence generally avoids 
+producing a temporary object, and instead issue calls to the Reducer as 
+values are produced by the evaluation of the value_sequence.
+
+You might have intended to remove the first AARM note completely - I couldn't 
+tell since you didn't mention them at all. (I don't think the first one says 
+much interesting, and in some sense it is wrong, since the evaluation is 
+likely to be different, at least at the generated code level, if the reduction 
+is parallel. Esp. if we have a container iterator.) The second note definitely 
+has value, since we want to say that even though this evaluated roughly like 
+an aggregate, we're not expecting an object to be created by the evaluation.
+
+> ---
+> 
+> Replace the paragraphs defining the V'Reduce attribute with the 
+> following:
+> 
+> The following attribute is defined for a value_sequence V:
+> 
+> V'Reduce (/reducer_/name, /initial_value_/expression[,
+> /combiner_/name])
+...
+
+I assumed that you were leaving the AARM notes alone. They still seem relevant 
+(although you might have simplified some of the wording had you edited them).
+
+
+
+It goes without saying that I had to delete a bunch of extra spaces after periods. :-)
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent