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

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

--- ai12s/ai12-0262-1.txt	2019/01/18 06:20:07	1.9
+++ ai12s/ai12-0262-1.txt	2019/01/28 04:47:36	1.10
@@ -237,56 +237,62 @@
 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:
+In the remainder of this subclause,
+we will refer to nonlimited subtypes Val_Type and Acc_Type of a
+reduction_attribute_reference. These subtypes and interpretations of
+the names and expressions of a reduction_attribute_reference
+are determined by the following rules:
 
    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:
+*  Acc_Type is a subtype of the expected type of the 
+   reduction_attribute_reference.
 
-   function Reducer(Accumulator : Acc_Type; Value : Val_Type) return Acc_Type;
+*  A /reducer subprogram/ is either subtype conformant with the following
+   specification:
 
-or is subtype conformant with the following specification:
+      function Reducer(Accumulator : Acc_Type; Value : Val_Type) return Acc_Type;
 
-   procedure Reducer(Accumulator : in out Acc_Type; Value : Val_Type);
+   or is subtype conformant with the following specification:
 
-A /combiner_/subprogram is a /reducer_/subprogram where both parameters are 
-of subtype Acc_Type.
+      procedure Reducer(Accumulator : in out Acc_Type; Value : in Val_Type);
 
-The reducer_name of a reduction_specification denotes a reducer_subprogram.
+*  A /combiner subprogram/ is a reducer subprogram where both parameters are 
+   of subtype Acc_Type.
 
-The combiner_name of a reduction_specification denotes a combiner_subprogram.
+*  The /reducer_/name of a reduction_specification denotes a reducer subprogram.
 
-The expected type of an initial_value_expression of a reduction_specification
-is that of subtype Acc_Type.
+*  The /combiner_/name of a reduction_specification denotes a combiner subprogram.
 
-The expected type of the expression of a value_sequence is that of
-subtype Val_Type.
+*  The expected type of an /initial_value_/expression of a reduction_specification
+   is that of subtype Acc_Type.
 
-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].
+*  The expected type of the expression of a value_sequence is that of
+   subtype Val_Type.
+
+*  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.5.2].
 
 Legality Rules
 
 The combiner_name of a reduction_specification shall be specified
-if the subtypes of the parameters of the /reducer_/subprogram denoted by the
-reduction_specification do not statically match each other and the
-reduction_attribute reference has a value_sequence with the reserved work
-parallel.
+if the subtypes of the parameters of the subprogram denoted by the
+reducer_Name of the reduction_specification do not statically match each 
+other and the reduction_attribute_reference has a value_sequence with 
+the reserved word parallel.
 
 AARM Reason:
 For a reduction_attribute_reference with a value_sequence that does not
@@ -328,25 +334,28 @@
 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:
+For a value_sequence V, the following attribute is defined:
 
-V'Reduce (/reducer_/name, /initial_value_/expression[, /combiner_/name])
+V'Reduce(Reducer, Initial_Value[, Combiner])
 
-   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
+   This attribute represents a /reduction expression/, and is in the form of a
+   reduction_attribute_reference.
+
+   The evaluation of a use of this attribute
+   begins by evaluating the value_sequence V and the parts of the
+   reduction_attribute_designator (the /reducer_/name Reducer, the
+   /initial_value_/expression Initial_Value, and the /combiner_/name Combiner,
+   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
+   (Value) parameter to a call on 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.
+   expression yields the final value of the accumulator. Combiner, 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
@@ -354,19 +363,20 @@
    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 a separate Combiner subprogram specified, then the accumulator for
+   each subsequence is initialized to the initial value, and 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
+   the subsequence, and calls on 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
+   expression have completed, Combiner (or Reducer, if Combiner is
+   not specified) 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
@@ -374,16 +384,12 @@
    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
+   If an exception is propagated by one of the calls on Reducer or
+   Combiner, 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.
 
@@ -391,11 +397,10 @@
 For a reduction_attribute_reference that has a value_sequence without the 
 parallel keyword, generally the compiler can still choose to execute the 
 reduction in parallel, presuming doing so would not change the results.
-However, if the combiner_name is not specified, then sequential
-execution is necessary if the subtypes of the parameters of the
-reducer_subprogram denoted by the reduction_specification do not statically
-match, since there is no subprogram identified in the construct that could be
-used for combining the results in parallel.
+However, if Combiner is not specified, then sequential
+execution is necessary if the subtypes of the parameters of Reducer do not 
+statically match, since there is no subprogram identified in the construct 
+that could be used for combining the results in parallel.
 
 AARM Discussion:
 
@@ -438,10 +443,6 @@
 
 Examples
 
-  --  Determine how many integers in an array are prime numbers
-
-  Prime_Count : constant Natural := [for P of A when Is_Prime(P) => 1]'Reduce("+",0);
-
   --  An expression function that returns its result as a Reduction Expression
 
   function Factorial(N : Natural) return Natural is
@@ -624,6 +625,61 @@
 complicated examples, it was found that writing a composite object as above
 provided better performance.
 
+!corrigendum 4.1.4(2)
+
+@drepl
+@xindent<@fa<attribute_reference>@fa<@ ::=@ >@fa<prefix>'@fa<attribute_designator>>
+@dby
+@xindent<@fa<attribute_reference>@fa<@ ::=@ >@hr
+@ @ @ @ @fa<prefix>'@fa<attribute_designator>@hr
+@ @ |@ @fa<reduction_attribute_reference>>
+
+!corrigendum 4.1.4(6)
+
+@drepl
+In an @fa<attribute_reference>, if the @fa<attribute_designator> is for an 
+attribute defined for (at least some) objects of an access type, then the 
+@fa<prefix> is never interpreted as an @fa<implicit_dereference>; otherwise 
+(and for all @fa<range_attribute_reference>s), if the type of the @fa<name>
+within the @fa<prefix> is of an access type, the @fa<prefix> is interpreted 
+as an @fa<implicit_dereference>. Similarly, if the @fa<attribute_designator>
+is for an attribute defined for (at least some) functions, then the 
+@fa<prefix> is never interpreted as a parameterless @fa<function_call>;
+otherwise (and for all @fa<range_attribute_reference>s), if the @fa<prefix>
+consists of a @fa<name> that denotes a function, it is interpreted as a 
+parameterless @fa<function_call>. 
+@dby
+In an @fa<attribute_reference> that is not a 
+@fa<reduction_attribute_reference>, if the @fa<attribute_designator> is for an 
+attribute defined for (at least some) objects of an access type, then the 
+@fa<prefix> is never interpreted as an @fa<implicit_dereference>; otherwise 
+(and for all @fa<range_attribute_reference>s), if the type 
+of the @fa<name>
+within the @fa<prefix> is of an access type, the @fa<prefix> is interpreted 
+as an @fa<implicit_dereference>. Similarly, if the @fa<attribute_designator>
+is for an attribute defined for (at least some) functions, then the 
+@fa<prefix> is never interpreted as a parameterless @fa<function_call>;
+otherwise (and for all @fa<range_attribute_reference>s), if the 
+@fa<prefix> consists of a @fa<name> that denotes a function, it is 
+interpreted as a parameterless @fa<function_call>. 
+
+!corrigendum 4.1.4(11)
+
+@drepl
+The evaluation of an @fa<attribute_reference> (or 
+@fa<range_attribute_reference>) consists of the evaluation of the @fa<prefix>. 
+@dby
+The evaluation of a @fa<range_attribute_reference> or an 
+@fa<attribute_reference> that is not a @fa<reduction_attribute_reference> 
+consists of the evaluation of the @fa<prefix>. The evaluation of a 
+@fa<reduction_attribute_reference> is defined in 4.5.10.
+
+!corrigendum 4.5.10(0)
+
+@dinsc
+
+Dummy to force a conflict.
+
 !ASIS
 
 ** Unknown.
@@ -1739,5 +1795,377 @@
 
 
 It goes without saying that I had to delete a bunch of extra spaces after periods. :-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, January 18, 2019  9:41 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? :-)
+
+I'll try to do this today.
+
+> 
+>> 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 presumed in an informal introduction, you could say "reference an attribute" 
+as equivalent to "make an attribute_reference," but I am fine if you want to 
+formalize the wording further.
+ 
+> 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.
+
+OK.
+
+> [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.
+
+Sorry, I had not noticed the Legality Rule.  The update began by just fixing 
+the Name Resolution rules, but then I realized that I had to restrict the 
+syntax to make Name Resolution straightforward, and never went back and 
+looked at the whole AI.
+ 
+>>    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)
+
+I presume you meant:
+
+   [for I in 1..1 => I]'Reduce ...
+
+> 
+> which is an even more complicated way to add 1 to A. So I just settled 
+> on "useless". :-)
+
+Fine.
+
+>> ---
+>> 
+>> 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).
+
+Fine.
+
+> 
+> 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.
+
+Agreed.
+
+> 
+>> ---
+>> 
+>> 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.
+
+Again, I was sort of trying to do a minimal change.  The notes that followed 
+didn't seem too bad as is, since we are talking about a "notional" array 
+aggregate.
+ 
+> 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.
+
+I am fine with them, thought they are of course not normative, and that is 
+as it should be in my view.
+ 
+>> ---
+>> 
+>> 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).
+
+Yes, again I was *trying* to make a minimal change.
+ 
+> It goes without saying that I had to delete a bunch of extra spaces 
+> after periods. :-)
+
+I hope I get some credit for being consistent... ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, January 21, 2019  7:57 PM
+
+... 
+> > 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)
+> 
+> I presume you meant:
+> 
+>    [for I in 1..1 => I]'Reduce ...
+
+That too. I did mean what I said, assuming that "+" is predefined or at least 
+acts like that, so that adding zero does nothing. I was trying to get the most
+insane way of adding one, and more that it does, the better. That's the 
+"point" of such contests, after all.
+
+...
+> >> 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.
+> 
+> Again, I was sort of trying to do a minimal change.  The notes that 
+> followed didn't seem too bad as is, since we are talking about a 
+> "notional" array aggregate.
+
+This weekend, I started worrying about that array aggregate in the case of a 
+parallel reduce.
+
+For a container iterator, an array aggregate always uses a forward 
+(sequential) iteration. (That would be more necessary, if such a thing is 
+possible, if we allow iteration filters.) And elements have to be evaluated in 
+iteration order. According to the above, adding "parallel" doesn't change this.
+
+Thus, it would be necessary to materialize the "notional" array aggregate in 
+order to apply any parallelism to the resulting "notional" array aggregate. 
+Moreover, we're not using any of the parallel iteration mechanism here.
+
+Note that the above wording works fine if (1) It is a sequential reduce; (2) 
+The iterator is the kind without an iterator_specification; (3) The iterator 
+doesn't support the parallel_iterator_interface. (2) might require a bit more 
+explanation: a regular iterator allows the expressions to be evaluated in an 
+arbitrary order, so there is no problem doing that in parallel without 
+materializing the aggregate. [Note that adding a filter will destroy this 
+property, it would have to be evaluated sequentially as with the other 
+iterators; it would require the two iteration model at a minimum, and I'd 
+expect that we'd share the wording.]
+
+What we want, I think, is to use the parallel iterator if it is available 
+and this is a parallel reduction. Also, note that the "length-determining" 
+pass is pointless for a reduction. So we probably do want to duplicate at 
+least some of the array aggregate wording here, because it can be simplified 
+and made to execute in parallel.
+
+Maybe something like:
+
+    For evaluation of a value_sequence that contains an 
+    iterator_specification, an iteration is performed for that 
+    iterator_specification (as described in 5.5.2), and for each value 
+    produced, the associated expression is evaluated, its value is converted
+     to Val_Type, and used to define the next value produced by the 
+    value_sequence. If the value_sequence includes the reserved word parallel, 
+    a parallel iteration is performed; otherwise, a sequential iteration is 
+    performed.
+
+    For the evaluation of some other 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.
+
+I think I'm missing some of the needed wording here (I lifted the first part 
+from the wording for array aggregates, but I'm not sure if we need to say more
+about the correspondence of the values with the nominal index values), but I 
+wanted to bring up this problem so we can consider fixes (or whether we want 
+to fix it).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Sunday, January 27, 2019  10:45 PM
+
+The definition of Parallel_Reduce reads:
+
+X'Parallel_Reduce(Reducer, Initial_Value[, Combiner])
+   X'Parallel_Reduce is a reduction expression that yields a result
+   equivalent to replacing the prefix of the attribute with the 
+   value_sequence:
+     [parallel for Item of X => Item]
+
+Let's try this:
+    X'Parallel_Reduce("+", 0)
+would give us:
+    [parallel for Item of X => Item]'Parallel_Reduce("+", 0)
+which is a bit of a problem, since there is no Parallel_Reduce attribute for a 
+value_sequence!
+
+We have to say something about the attribute identifier as well:
+
+X'Parallel_Reduce(Reducer, Initial_Value[, Combiner])
+   X'Parallel_Reduce is a reduction expression that yields a result
+   equivalent to replacing the attribute identifier with Reduce and
+   prefix of the attribute with the value_sequence:
+     [parallel for Item of X => Item]
+
+---
+
+None of these attributes ever say that they are in the form of 
+reduction_attribute_references. That seems kinda important, since the 
+resolution rules are based on that. I suppose that we can skip that 
+information for the object forms, since they are defined by equivalence, 
+but not for the value_sequence form.
+
+---
+
+Also, the value_sequence form starts:
+
+For a value_sequence V, the following attribute is defined:
+
+V'Reduce(/reducer_/name, /initial_value_/expression[, /combiner_/name])
+
+This attribute name is far too long to fit into the existing attribute annex, 
+it would extend all the way across the page or beyond. Moreover, we want 
+these parts to come from the definition for a reduction_attribute_designator 
+and not from this description. Note that First is defined as
+
+First(N)
+
+and not
+
+First(/static_/expression)
+
+So, for these last two issues, I suggest redoing this as:
+
+V'Reduce(Reducer, Initial_Value[, Combiner])
+
+   This attribute represents a /reduction expression/, and is in the form of a
+   reduction_attribute_reference.
+
+   The evaluation of a use of this attribute
+   begins by evaluating the value_sequence V and the parts of the
+   reduction_attribute_designator (the /reducer_/name Reducer, the
+   /initial_value_/expression Initial_Value, and the /combiner_/name Combiner,
+   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/). 
+
+   ...
+
+---
+
+The original wording for this AI had "reducer_subprogram" and 
+"combiner_subprogram" all over the place, but such syntax was not defined. We 
+don't want to use syntax terms that don't actually relate to the syntax. 
+Luckily, there isn't much use of those that can't be easily replace by 
+"subprogram denoted by the reducer_name" or just Reducer (in the attribute 
+definition).
+
+Since this AI will be revoted at the next meeting (because of the extensive 
+wording changes), I won't try to record all of this in detail.
+
+---
+
+Attributes have to be introduced
+
+For blah, the following attributes are defined:
+
+Otherwise, the tools don't work (the attribute annex is created directly out 
+of the attribute text, I can't reorder anything).
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent