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

Differences between 1.13 and version 1.14
Log of other versions for file ai12s/ai12-0242-1.txt

--- ai12s/ai12-0242-1.txt	2018/10/19 05:59:55	1.13
+++ ai12s/ai12-0242-1.txt	2019/01/11 05:38:16	1.14
@@ -1,430 +1,187 @@
-!standard 4.5.9 (0)                                18-10-16    AI12-0242-1/06
+!standard 4.5.9 (0)                                19-01-10    AI12-0242-1/07
 !class Amendment 14-06-20
 !status work item 14-06-20
 !status received 14-06-17
 !priority Medium
 !difficulty Hard
-!subject Reduction Expressions
+!subject Shorthand Reduction Expressions for Objects
 !summary
 
-Two New Attributes are introduced to facilitate reduction;
-A Reduce Attribute for sequential reduction and a Parallel_Reduce
-Attribute for parallel reduction.
+The 'Reduce and 'Parallel_Reduce are defined to allow Reduction Expressions
+to be applied to array objects and iterable container objects without needing
+to write a value_generator.
 
 !problem
 
-A common problem in computing is the need to summarize a set of values.
+The facilities of AI12-0262-1 provide a expressive means to write reduction
+expressions in the form of an attribute reference. A common need for
+reductions is to summarize the values of an array or iterable container
+object. Using the syntax of AI12-0262-1, one could write an expression
+such as the following to produce the sum of all components of an array or
+elements of a container;
+
+    Sum : constant Integer := [for Value of A => Value]'Reduce("+", 0);
+
+    Where A is an object of an array or an iterable container object.
+
+Since applying reduction expressions to summarize the components of an
+array or the elements of a containers is expected to be a common
+usage for reduction expression, it would be convenient if there were a
+shorthand form where the value_generator syntax could be replaced with a
+simple prefix that is a name denoting an array or iterable container object.
+
+eg.   The above statement could be rewritten as;
+
+    Sum : constant Integer := A'Reduce("+", 0);
+
+Also, one of the goals of the Reduction Expression syntax in AI12-0262-1 is
+to provide explicit parallelism. Using the syntax of that AI, that
+can be accomplished by inserting the parallel keyword in the value_generator
+specification. For example, the original statement above could be written
+as;
+    Sum : constant Integer := [parallel for Value of A => Value]'Reduce("+", 0);
 
-Currently in Ada, one generally has to write a subprogram to do this, which
-involves writing a loop to iterate through the set of values, and a global
-accumulator variable or set of variables that get updates through each iteration
-of the loop.
-
-One of the most important addition to Ada in Ada 2012 is contract specifications
-for subprograms. However to write pre and post conditions that attempt to
-summarize inputs or outputs, one has to write a subprogram to express the
-summary result, which can add clutter to an API for an abstraction, and also
-injects a level of indirection, where if a client wants to understand the
-requirements of the pre condition, or the effects of the post condition, one has
-to find and examine the body of the subprogram named in the contract
-specification.
-
-It would be useful if such summarizations could be expressed in a simpler, more
-concise manner, such as an expression, without always having to write another
-subprogram. The proposed solution is to allow an Attribute to be applied to an
-array object or iterable container object to provide the summarization.
-
-Ada 83 was already a pretty good language for "hybrid" functional/imperative
-programming, because you can have a sequence of declarations that progressively
-compute a desired result.  Often it was only because you needed to enter a loop
-that you had to do any significant amount of computing after the "begin."  In
-today's Ada, with conditional expressions, quantified expressions, the recently
-approved iterated component association, and our newly proposed container
-aggregates, the need for explicit ifs and loops after the "begin" is continuing
-to decrease.  There appears to be a shift in the a balance between functional
-and imperative features, more towards the functional side.  There is a
-resurgence of interest in functional programming these days, but going all the
-way to "pure functional" programming, with "monads" instead of assignment
-statements, and recursion only with no iteration, would be too going too far
-towards the functional side, but it is important to "complete" the functional
-primitives, if only to give the desired power to Ada's contract-based
-programming.
-
-Some of the existing syntax in Ada already can provide forms of summarization.
-For example, a quantified expression can be viewed as being a special purpose
-Reduction Expression that applies an operation, the Predicate, to a set of
-values to reduce the predicate results to a single Boolean result. Similarly, an
-array aggregate in the form of an iterated_component_association can also be
-viewed as being a special purpose Reduction Expression that applies an
-operation, in place concatenation, to a set of values to reduce into an array
-result. A Reduction expression is a more general syntactic form where there is
-less constraint on the type of operation to be applied to summarize the set of
-values, and the operation can produce result values of types other than
-Boolean values, or array creation.
-
-Such a reduction capability is the last remaining major component needed to
-complete the "iterated" operations. There are many applications of reduction
-capabilities, including both sequential and parallelism usage.  It will often be
-the right way to define, in a postcondition, what is the final value of one
-output of the subprogram, even though the subprogram might have multiple outputs
-and might do many other things.
-
-Such a capability can allow programmers to express algorithms more concisely,
-which tends to also make the algorithms easier to read, debug, understand, and
-maintain.
-
-Another need is to be able to perform reductions in parallel. Modern computing
-platforms typically provide support for multicore computing, yet writing
-algorithms that take advantage of these multicore platforms is considerably
-difficult to write, very error prone, and difficult to debug. Many of the divide
-and conquer parallelism algorithms involve reduction, commonly known as
-MapReduce, in the parallelism world. The challenge with such reductions is that
-writing a subprogram with a global accumulator value normally would imply a data
-race if multiple threads of execution end up updating the global variable in
-parallel.
-
-Parallel reduction is in many ways a separate issue, when compared to sequential
-reduction, and where (and whether) it is best inserted depends heavily on the
-amount of computing done within a single iteration, the independence of those
-computations, and the number of iterations.  The advantage of the notations like
-quantified expressions, container aggregates, and reduction expressions, is that
-they are self-contained, and can often be analyzed holistically by the compiler
-to determine whether and where to insert parallelism. It is important in the
-context of Ada to have sufficient annotations to allow the compiler to both
-check the safety of explicit parallelism, and also safely insert implicit
-parallelism. Hence the importance of the Global and Nonblocking annotations.
-
-It is also important to allow the programmer to indicate explicitly whether
-parallelism should be applied, as it documents to the reader that performance
-is important to the user, and makes it clear that parallelism is to be applied.
-For instance, a compiler might choose to conservatively apply parallelism,
-only in cases where it can statically determine that the performance would
-be guaranteed to benefit from the parallelism. A programmer might want to
-override the conservatism of the compiler and experiment with parallelism to
-measure the benefits, and then deploy the code in the form that provided the
-optimal performance. This is why the Parallel_Reduce attribute is included
-in this proposal.
+It would be desirable if a shorthand form could be provided that still
+allows the programmer to explicitly request parallel execution for the
+expression.
 
 !proposal
 
-This proposal depends on the facilities for aspect Global (AI12-0079-1) and for
-aspect Nonblocking (AI12-0064-2). Those proposals allow the compiler to
-statically determine where parallelism may be introduced without introducing
-data races. This proposal also depend on parallel iteration support for
-containers (AI12-0266-1).
-
-The goals of this proposal are to provide a mechanism for expressing a
-summarization of a set of values. Such a summarization is known as a reduction.
-It is desired that such a mechanism;
-
-- is easy to understand
-- is easy to write/express
-- allows parallelization
-- provides safety by eliminating data races and logic errors.
-- fits in well with existing Ada syntax
-
-This model proposes two new attributes, 'Reduce, and 'Parallel_Reduce which can
-be used to combine the component values of an array or the element values
-of an iterable container object, into a single result value.
-
-This mechanism is called reduction. The 'Reduce attribute is
-intended to provide sequential reductions by default, unless the compiler can
-determine it is safe and beneficial to performance to implicitly introduce
-parallelism. The 'Parallel_Reduce attribute is intended to allow the programmer
-to explicitly request that a reduction be performed in parallel, which is useful
-because the compiler is not always able to make a correct assessment statically
-whether injecting parallelism will improve instead of detract from performance.
-Also, a compiler may not have the semantic knowledge to know how to combine
-the results of multiple logical threads of control when the subtype of the result
-is different than the subtype of the values being summarized.
-
-When a compiler cannot make the determination whether parallelism is worthwhile,
-or cannot determine how to apply the parallelism, it is likely to choose
-sequential processing because it is simpler, and more deterministic. By allowing
-the programmer to request parallelism explicitly, the compiler does not need to
-make the assessment, and the programmer can easily revert to sequential
-processing by simply replacing the parallel version of the attribute with
-the sequential one.
-
-Both the Reduce and Parallel_Reduce attributes allow the programmer to
-name a user defined reducer subprogram to combine values from two iterations
-into a single value. The Parallel_Reduce attribute also allows the programmer
-to specify a user defined combiner subprogram to combine the results from
-multiple logical threads of control. This is needed in cases where the
-subtypes of the reducer subprogram parameters are not the same. If the subtypes
-of the reducer subprogram parameters are the same, then if the combiner subprogram
-is not specified, the reducer subprogram is also implicitly used as the
-combiner subprogram.
-
-The Parallel_Reduce attribute activates the necessary static checks (see
-AI12-0267-1) of the compiler to ensure that the parallelism can safely be
-introduced, without necessarily requiring analysis to determine if there is a
-performance benefit to the parallelism.
-
-The prefix of the 'Reduce and 'Parallel_Reduce attribute is either an array
-object or an iterable container object. This includes objects created by
-array aggregates, or iterable container object aggregates (see AI12-0212-1).
-
-For parallel execution, the user supplied reducer subprogram and combiner
-subprogram can be non-commutative (e.g. vector concatenation), as it is expected
-that the implementation will ensure that the results of the logical threads of
-control are combined while preserving the original ordering of the set of input
-values of the attribute prefix as would be consistent with sequential execution.
+This proposal depends on parallel iteration support for
+containers (AI12-0266-1) and AI12-0262-1 which provides general support for
+reduction expressions.
+
+The proposal is to extend the syntax for reduction expressions to allow
+the value_generator to be replaced with a prefix that denotes an array
+object or iterable container object. To allow parallelism to be explicitly
+requested for this shorthand form, a new attribute, 'Parallel_Reduce is
+defined. The 'Reduce shorthand form is synatically equivalent to writing
+a value_generator that produces values for all array components or container
+elements without the parallel keyword specified, and the 'Parallel_Reduce
+is syntatically equivalent to the same but with the parellel keyword specified.
 
 !wording
-
-Replace 4.1.4(3/2):
- 
-attribute_designator ::=
-    identifier[(static_expression)]
-  | identifier(reduction_specification)
-  | Access | Delta | Digits | Mod
-
-Add a new subclause 4.5.9:
-
-4.5.9 Reduction Expressions
-
-A Reduction expression provides a way to write a value that denotes a
-combination of the component values of an array or of the
-element values stored in an /iterable container object/
-(see 5.5.1).
-
-Syntax
-
-reduction_specification ::= /reducer_/name, /initial_value_/expression[, /combiner_/name]
-
-A /Reduction Expression/ is an attribute reference where the identifier
-of the attribute_reference is Reduce or Parallel_Reduce and the expression
-of the attribute_designator is a reduction_specification.
-
-Name Resolution Rules
-
-The expected type of a reduction expression shall be a single nonlimited 
-type R.
-
-AARM TO BE Honest: R is really a subtype, and we call it that below, but it 
-gets confusing to call the "expected type" a subtype.
-
-For a subtype S of a component of an array type A or element of an
-iterable container object C and a corresponding object O of the
-array or iterable container object, which is denoted
-by the prefix of a reduction_expression:
 
-A /reducer_/subprogram either denotes a function with the following
-specification:
+Modify 4.1.4(6)
 
-   function Reducer(Accumulator : R; Value : S) return R with Non_Blocking, Global => null;
+In an attribute_reference, if the attribute_designator is for an attribute
+defined for (at least some) objects of an access type, then the prefix is
+never interpreted as an implicit_dereference; otherwise (and for all
+range_attribute_references {and reduction_attribute_references}),
+if the type of the name within the prefix is of an access type, the prefix is
+interpreted as an implicit_dereference. Similarly, if the attribute_designator
+is for an attribute defined for (at least some) functions, then the prefix
+is never interpreted as a parameterless function_call; otherwise (and for
+all range_attribute_references {and reduction_attribute_references}), if
+the prefix consists of a name that denotes a function, it is interpreted
+as a parameterless function_call.
+
+Modifies 4.1.4(14/2)
+
+In general, the name in a prefix of an attribute_reference{,}[(or a]
+range_attribute_reference{, or a reduction_attribute_reference}) has to be
+resolved without using any context. However, in the case of the Access attribute,
+the expected type for the attribute_reference has to be a single access type,
+and the resolution of the name can use the fact that the type of the object
+or the profile of the callable entity denoted by the prefix has to match the
+designated type or be type conformant with the designated profile of the
+access type.
+
+Modifies 4.1.4(14.a/2)
+
+Proof: In the general case, there is no "expected type" for the prefix of
+an attribute_reference{ (or reduction_attribute_reference)}. In the special
+case of 'Access, there is an "expected type" or "expected profile" for the
+prefix.
 
-or denotes a procedure with the following specification:
 
-   procedure Reducer(Accumulator : in out R; Value : S) with Non_Blocking, Global => null;
+[Modifications to new subclause 4.5.9 added by AI12-0262-1]
 
-A /combiner_/subprogram is a /reducer_/subprogram where subtypes S and R
-statically match.
+Modify Syntax of 4.5.9:
 
-The reducer_name of a reduction_specification denotes the name of a
-reducer_subprogram.
+reduction_attribute_reference ::= value_generator'reduction_attribute_designator
+                                {| prefix'reduction_attribute_designator}
 
-The expected type of an initial_value_expression of a reduction_specification
-is of subtype R.
+Modify AARM Note in Legality Rules of 4.5.9:
 
-The combiner_name of a reduction_specification denotes the name of a
-combiner_subprogram.
-
-Legality Rules
-
-For a reduction_expression where the attribute_reference is Reduce,
-there shall not be a combiner_name specified.
-
-For a reduction_expression where the attribute_reference is Parallel_Reduce,
-the combiner_name shall be specified if subtype S and subtype R do not
-statically match.
-
 AARM Note
-The combiner_name is always optional for Reduce, because only one
+For a reduction_attribute_reference with a value_sequence that does not
+have the {reserved word} parallel [keyword]{or has a prefix and the
+identifier of the reduction_attribute_designator is Reduce}, the
+combiner_name of the reduction_specification is optional because only one
 logical thread of control is presumed so there is no need to provide a
 way to combine multiple results.
 
+Add Legality rule to subclause 4.5.9:
+
+If the identifier of a reduction_attribute_designator is Parallel_Reduce
+then the combiner_name of the reduction_specification shall be specified if
+the subtypes of all the parameters of the /reduce_/subprogram denoted by
+the reduction_specification do not statically match.
+
 Static Semantics
+
+For a reduction_attribute_reference where the identifier of the
+reduction_attribute_designator is Parallel_Reduce, if the combiner_name
+is not specified, then the subprogram denoted by the reducer_subprogram also
+implicitly denotes the combiner_subprogram.
 
-For a reduction_expression where the attribute_reference is Parallel_Reduce,
-if the combiner_name is not specified, then
-the subprogram denoted by the reducer_subprogram also implicitly denotes the
-combiner_subprogram.
+Modify AARM note in Static Semantics of 4.5.9:
+AARM Note:
+For a reduction_attribute_reference that has a value_sequence without the
+parallel keyword {or a prefix where the identifer is Reduce}, if the
+combiner_name is not specified, then sequential execution is presumed 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.
 
 Dynamic Semantics
 
 The following attributes are defined for a prefix O that is of an
-array type (after any implicit dereference), or denotes a constrained array subtype,
-or denotes an /iterable container object/:
+array type (after any implicit dereference), or denotes an /iterable container
+object/:
 
-O'Reduce(Reducer, Initial_Value)
+O'Reduce(Reducer, Initial_Value[, Combiner])
 
-   O'Reduce is a reduction expression that initializes the result of the
-   expression to the Initial_Value, and then uses an array component iterator
-   or a component element iterator to iterate in increasing order
-   through the values associated with the attribute prefix and issues calls
-   to Reducer using the value of the loop parameter or loop cursor as the
-   Value parameter for each iteration, and using the result of the previous
-   iteration as the Accumulator parameter. Yields the final result after
-   the iteration is complete. If the prefix of the attribute reference
-   denotes a null range of values, then yields the Initial_Value.
+   O'Reduce is a reduction expression that yields a result equivalent to
+   replacing the prefix of the attribute with the value_generator;
+   [for Item of O => Item]
 
-O'Parallel_Reduce(Reducer, Initial_Value[, Combiner])
 
-   O'Parallel_Reduce is identical to O'Reduce except that O'Parallel_Reduce
-   is a parallel construct where the iterations are divided among multiple
-   logical threads of control. Each logical thread of control
-   generates a local copy of the result of its iteration, which is initialized
-   to the value of the loop parameter or loop cursor associated with the first assigned
-   iteration. The Reducer is called for subsequent iterations when multiple
-   iterations have been assigned to the same logical thread of control.
-   As each logical thread of control completes its assigned
-   iterations, the Combiner is called using the value of the local
-   result as the Value parameter of the call, and using the previous
-   final result value, as the the Accumulator parameter for the call.
-   Once all logical threads of control have completed, yields the result
-   of the last call to Combiner. If the prefix of the attribute reference
-   denotes a null range of values, then yields the Initial_Value.
-   The calls to Combiner are issued sequentially 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.
-
-AARM Note
-The prefix can be a (qualified) array or aggregate for an
-/iterable container object/. The prefix can denote an object of a
-multi-dimensional array.
-
-AARM Note:
+O'Parallel_Reduce(Reducer, Initial_Value[, Combiner])
 
-We say the calls to Combiner are sequentially ordered in increasing order
-because certain reductions, such as vector concatentation,
-can be non-commutative operations. In order to return a
-deterministic result for parallel execution that is consistent with
-sequential execution of the 'Reduce attribute, we need to specify an order
-for the iteration in both the 'Reduce and 'Parallel_Reduce cases,
-and for the combination of results from the logical threads of control
-for the 'Paralell_Reduce case.
+   O'Parallel_Reduce is a reduction expression that yields a result
+   equivalent to replacing the prefix of the attribute with the value_generator;
+   [parallel for Item of O => Item]
 
 Examples
 
-  Calculate the sum of elements of an array of integers
+  --  Calculate the sum of elements of an array of integers
 
   A'Reduce("+",0)  -- See 4.3.3(43)
 
-  Determine if all elements in a two dimensional array of booleans are set to
-  true
+  --  Determine if all elements in a two dimensional array of booleans
+  --  are set to true
 
-  Grid'Reduce("and", true);  -- See 3.6(30)
+  Grid'Reduce("and", true)  -- See 3.6(30)
 
-  Calculate the minimum value of an array of integers in parallel
+  --  Calculate the minimum value of an array of integers in parallel
 
   A'Parallel_Reduce(Integer'Min, Integer'Last)
 
 !discussion
-
-We considered whether 'Reduce should allow reducer_subprograms without
-the Nonblocking aspect and Global=>null aspect specification, since
-strictly speaking that isn't necessary if the reduction does not execute
-in parallel. We could relax this in the future if it is needed, but typically
-most reducers are short simple functions, and typically will be nonblocking
-without global involving global variables. Since the aspects are needed
-for the reducer subprograms used with 'Parallel_Reduce, it was simpler
-to use the same specification for both attributes.
-
-We similarly considered whether the specification of the combiner_subprogram
-of 'Parallel_Reduce could be relaxed, since the calls to the
-combiner_subprogram need to be called sequentially since they update the
-final global result. However, while the calls to the combiner_subprogram
-need to be sequential with respect to each other, an implication could
-run these calls in parallel with other logical threads of control as
-part of the processing associated with calling the reducer_subprograms.
-This increases the parallelism of the overall processing which may
-provide performance benefits.
-
-For an example on how this can be accomplished while supporting non-commutative
-reduction, see the article Parallel Reduction Lists, in the June 2016 issue
-of the Ada User Journal at http://www.ada-europe.org/auj/archive/. Since
-calling the combiner_subprogram in parallel with other processing
-is a possibility, we need the global=>null and Nonblocking aspects for
-the combiner_subprogram associated with 'Parallel_Reduce to
-ensure this is safe to do without risking data races and deadlocking.
-
-We considered defining an Associative aspect that could be specified on
-subprograms, and then having the compiler check that the reducer_subprogram
-and combiner_subprogram have that aspect specified as True for the
-'Parallel_Reduce. Although it is true that the reducer_subprogram and
-combiner_subprogram need to be associative operations for parallelism
-to be applied, there are a number of problems with this. First of all,
-the compiler cannot verify if a particular call is truly associative,
-so the compiler would have to have faith in the programmer to get this right.
-Secondly, associativity can sometimes be in the eye of the beholder.
-For example, integer addition is normally considered an associative
-operation, but if integer overflow is a possibility, then technically
-the operation is not associative. That might be an important consideration
-for some users, and unimportant to others. Similarly, floating point math
-is not associative, due to the rounding errors that get introduced, but
-for many users, the results are good enough to consider as being associative.
-Thirdly, this added a lot of complexity and wording changes to the AI,
-which was deemed to not be worthwhile.
-
-We considered whether the initial_value was needed or not. We could
-alternatively overload the attribute names to provide versions that do not
-accept a second argument.
-
-This however, means that there can be a question about what the expression
-should evaluate to, if the prefix of the attribute specifies a null range of
-values. Likely, an exception would need to be raised, but that can add
-complexity for uses such as contracts, since handling the exception case would
-need to be considered. We decided that for now at least, it is better to keep
-the interface simple. If an exception is needed for a null range, there are
-other ways to do that already in the language.
-
-Another concern might be about the need to perform multiple reductions at the
-same time.
-
-Consider:
-
-   Sum : Integer := A'Reduce("+", 0):
-   Min : Integer := A'Reduce(Integer'Min, Integer'Last);
-   Max : Integer := A'Reduce(Integer'Max, Integer'First);
-
-Here we have three calculations that might ideally occur in parallel, but here
-would normally be expected to execute sequentially with respect to each other.
-
-One might want to calculate these three results iterating only once through the
-array.
-
-This can be accomplished by creating a composite result type, and writing a
-user-defined reducer function.
 
-   type Summary is
-      record
-         Sum : Integer;
-         Min : Integer;
-         Max : Integer;
-      end record;
-
-   -- Identity value for the Reduce function
-   Identity : constant Summary := Summary'(Sum => 0,
-                                           Min => Integer'Last,
-                                           Max => Integer'First);
-
-   -- Reducer function for the Reduction expression
-   function Reduce (L, R : Summary)
-       return Summary with Nonblocking, Globals => null is
-     (Summary'(Sum => L.Sum + R.Sum,
-               Min => Integer'Min (L.Min, R.Min),
-               Max => Integer'Max (L.Max, R.Max)));
-
-   -- Reduction expression to compute all 3 results at once
-   Result : constant Summary := A'Reduce(Reduce, Identity);
-
-It was also noted here during performance testing that better times were
-collected by actually writting 3 separate reductions, however in other more
-complicated examples, it was found that writing a composite object as above
-provided better performance.
+We considered whether the Parallel_Reduce attribute should be eliminated.
+This would provide the benefit of there being only a single attribute
+reference needed for reduction, Reduce. Furthermore, explicit parallelism for
+reduction expressions would still be possible, because one could always replace
+the prefix of the attribute reference with the equivalent value_generator,
+[parallel for Item of X => Item], which does not seem to be too much of a
+hardship. In the end, we decided to provide Parallel_Reduce for the same reason
+that we provide the short form for the Reduce attribute. As a convenience for
+the programmer, and to make it easier to switch back and forth between a
+parallel and a sequential implementation by making minimal changes to the code.
 
 !ASIS
 
@@ -7925,12 +7682,12 @@
 From: Tucker Taft
 Sent: Monday, October 15, 2018  8:29 PM
 
-> This minutes say "Steve wonders if we would ever want a 'Reduce to be 
-> static. We'll leave that for the AI author.". I think a better answer 
+> This minutes say "Steve wonders if we would ever want a 'Reduce to be
+> static. We'll leave that for the AI author.". I think a better answer
 > here would have been "no". :-)
 
-I would agree with Randy here -- static expressions are important in some 
-contexts, such as the choices in a case statement, or the string argument 
+I would agree with Randy here -- static expressions are important in some
+contexts, such as the choices in a case statement, or the string argument
 of a pragma Export (for example).  In other cases, compile-time evaluation
 without being officially static is fine, and that's all we would ever hope
 for here, as far as I am concerned, and compile-time evaluation is purely an
@@ -7942,74 +7699,74 @@
 Sent: Tuesday, October 16, 2018  9:06 PM
 
 > Brad writes:
->>    - Reduction expressions may be static expressions for the 'Reduce 
+>>    - Reduction expressions may be static expressions for the 'Reduce
 >> case, if the reducer_subprogram denotes a static function.
 >>
 > and in the AI:
 >>
 >>Add after 4.9(8)
 >>
->>"a reduction_expression whose prefix statically denotes a statically 
->>constrained array object or array subtype, and whose 
->>attribute_designator is Reduce, and whose reducer_subprogram denotes a 
+>>"a reduction_expression whose prefix statically denotes a statically
+>>constrained array object or array subtype, and whose
+>>attribute_designator is Reduce, and whose reducer_subprogram denotes a
 >>static functions;"
-> 
-> Umm, this doesn't require the components of the prefix to be static. 
-> That seems rather fundamental to the definition of a static 
-> expression! Also, Ada currently doesn't have any static composite 
-> types other than strings; I have to wonder the wisdom of introducing 
-> them by a single special case, rather than some larger generalization 
-> of static expressions. (Static strings, after all are a hack to 
+>
+> Umm, this doesn't require the components of the prefix to be static.
+> That seems rather fundamental to the definition of a static
+> expression! Also, Ada currently doesn't have any static composite
+> types other than strings; I have to wonder the wisdom of introducing
+> them by a single special case, rather than some larger generalization
+> of static expressions. (Static strings, after all are a hack to
 > support interfacing.)
-> 
-> This minutes say "Steve wonders if we would ever want a 'Reduce to be 
-> static. We'll leave that for the AI author.". I think a better answer 
+>
+> This minutes say "Steve wonders if we would ever want a 'Reduce to be
+> static. We'll leave that for the AI author.". I think a better answer
 > here would have been "no". :-)
 
 Fine by me. It was sort of a Hail-Mary pass into the static end-zone to see if
-my receiver Steve could catch it. Looks like the pass was intercepted, (or 
+my receiver Steve could catch it. Looks like the pass was intercepted, (or
 more likely, I fumbled it).
 
 > ----
-> 
+>
 >>Syntax
 >>
->>reduction_specification ::= /reducer_/name, 
+>>reduction_specification ::= /reducer_/name,
 >>/initial_value_/expression[,
 > ...
 >>
->>A /Reduction Expression/ is an attribute reference where the 
->>identifier of the attribute_reference is Reduce or Parallel_Reduce and 
+>>A /Reduction Expression/ is an attribute reference where the
+>>identifier of the attribute_reference is Reduce or Parallel_Reduce and
 >>the expression of the attribute_designator is a reduction_specification.
-> 
-> A reduction_specification is not an expression, so the above 
-> description is nonsense. You need to define this completely if you are 
+>
+> A reduction_specification is not an expression, so the above
+> description is nonsense. You need to define this completely if you are
 > going to do any of it this way:
-> 
+>
 > Replace 4.1.4(3/2):
-> 
+>
 > attribute_designator ::=
 >    identifier[(static_expression)]
 >  | identifier(reduction_specification)
 >  | Access | Delta | Digits | Mod
-> 
+>
 > [Note: I just made Steve do that same thing with his AI12-0243-1.]
 
 Ok Thanks!
 
 > ----
-> 
+>
 >>The expected type of a reduction expression is any nonlimited type.
-> 
-> This is fine, but then you say "R" is the expected type of the 
-> reduction expression -- but you just said that that is any nonlimited 
-> type. Can't have it both ways in a single set of Name Resolution 
-> Rules. Somewhere, "R" needs to be a single specific type (or whatever it is 
+>
+> This is fine, but then you say "R" is the expected type of the
+> reduction expression -- but you just said that that is any nonlimited
+> type. Can't have it both ways in a single set of Name Resolution
+> Rules. Somewhere, "R" needs to be a single specific type (or whatever it is
 > restricted to).
 
-I'm not sure I understand this comment, but what I am trying to say is that 
-"R" is of the same type as the expected type of the expression. That is, 
-first the expected type is resolved, (based on context) then once you know 
+I'm not sure I understand this comment, but what I am trying to say is that
+"R" is of the same type as the expected type of the expression. That is,
+first the expected type is resolved, (based on context) then once you know
 that, you can resolve the reduction_expression.
 
 Or perhaps I should say that "R" is of any nonlimited type, and then say that
@@ -8021,39 +7778,39 @@
 From: Randy Brukardt
 Sent: Tuesday, October 16, 2018  9:46 PM
 
-> I'm not sure I understand this comment, but what I am trying to say is 
-> that "R" is of the same type as the expected type of the expression. 
-> That is, first the expected type is resolved, (based on context) then 
+> I'm not sure I understand this comment, but what I am trying to say is
+> that "R" is of the same type as the expected type of the expression.
+> That is, first the expected type is resolved, (based on context) then
 > once you know that, you can resolve the reduction_expression.
-> 
-> Or perhaps I should say that "R" is of any nonlimited type, and then 
-> say that the expected type of a reduction expression is the type or 
+>
+> Or perhaps I should say that "R" is of any nonlimited type, and then
+> say that the expected type of a reduction expression is the type or
 > "R"? Or am I still missing something?
 
-All of the rules of type resolution are applied simultaneously (unless 
+All of the rules of type resolution are applied simultaneously (unless
 otherwise defined). So you can't have conflicting rules or rules that need
 an order unless you say that.
 
-I presume you want this to resolve like an aggregate (don't look inside until 
-the outside is figured out). If you look at those rules, they all say that 
+I presume you want this to resolve like an aggregate (don't look inside until
+the outside is figured out). If you look at those rules, they all say that
 the type has to be a single type. Probably that's all you need to do here:
 
    The expected type of a reduction expression shall be a single nonlimited type.
 
-You need "single" so that nothing from the "inside" of the reduction can 
-affect the outside. Otherwise, if you had two possible types A and B, one 
+You need "single" so that nothing from the "inside" of the reduction can
+affect the outside. Otherwise, if you had two possible types A and B, one
 would have to try both as R and if exactly one worked, that would resolve.
 As noted above you don't want that.
 
 You might as well define the R here too:
 
-   The expected type of a reduction expression shall be a single nonlimited 
+   The expected type of a reduction expression shall be a single nonlimited
    type R.
 
-and then you can drop the other part defining that name. (Then there's no 
+and then you can drop the other part defining that name. (Then there's no
 apparent conflict.)
 
-I'll just make this change with the others from your message unless you tell 
+I'll just make this change with the others from your message unless you tell
 me not to.
 
 ****************************************************************
@@ -8061,14 +7818,14 @@
 From: Brad Moore
 Sent: Tuesday, October 16, 2018  9:58 PM
 
-> I'll just make this change with the others from your message unless 
+> I'll just make this change with the others from your message unless
 > you tell me not to.
 
 That sounds great Randy! Please do make that change with the others, but I
 am not sure how you'd handle the subtype S. Would that need "single" as well?
 It sounds like it would. And note it is not necessarily the same type as
 subtype R, in fact, it could be of any type (including limited ones, I think,
-so long as the Nonblocking aspect requirement is being met by the denoted 
+so long as the Nonblocking aspect requirement is being met by the denoted
 reducer_subprogram and combiner_subprogram)
 
 ****************************************************************
@@ -8076,11 +7833,11 @@
 From: Randy Brukardt
 Sent: Tuesday, October 16, 2018  10:44 PM
 
-I don't think it is necessary, as S is the component type of the array type 
-of O (or a similar case for containers), it's not really a free type. 
+I don't think it is necessary, as S is the component type of the array type
+of O (or a similar case for containers), it's not really a free type.
 
 In particular, the prefix of an attribute does not have an expected type, it
-has to be resolved without context. (That's because the prefix of most 
+has to be resolved without context. (That's because the prefix of most
 attributes don't have an expected type - you DON'T want to change that here!)
 Thus, one does resolution of the prefix early.
 
@@ -8091,8 +7848,55 @@
    Now (and only now), one can apply resolution to the "inside"
    of the reduction. All of those types are known, so that's pretty simple.
 
-The wording you have seems to capture this, perhaps not that clearly, but I 
-don't have a better idea at the moment. Let Tuck and the others at it next 
+The wording you have seems to capture this, perhaps not that clearly, but I
+don't have a better idea at the moment. Let Tuck and the others at it next
 week.
+
+****************************************************************
+
+From: Brad Moore
+Sent: Thursday, January 10, 2019  12:26 AM
+
+Attached is my homework related to AI12-0242-01.
+
+This AI is a small shadow of its former self.
+
+It used to be that AI12-0262-01 was based as an extension to this AI.
+
+Now it is the other way round, which will makes sense when you look at this AI.
+
+The array and container object reduction is now just a shorthand for the
+reduction capabilities of AI12-0262-01.
+
+That is,
+
+O'Reduce(...) is equivalent to writing [for Item of O => Item]'Reduce(...)
+
+and
+
+O'Parallel_Reduce(...) is equivalent to writing [parallel for Item of O =>
+Item]'Reduce(...)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 10, 2019  11:36 PM
+
+A few minor changes to this.
+
+I shortened the title, as I've been getting complaints about them being too
+long. And we don't need all of the details in the title, just an idea of what it
+is about.
+
+So I used "Shorthand Reduction Expressions for Objects".
+
+Typo: ... or the elements of a container[s] ...
+
+There's a bunch of ******* in lines in the wording. I suspect there are
+left-over editing markers for you, and the need to go. And 4.5.9 is a subclause,
+not a "section" (you can refer to Legality Rules that way if you like, but I try
+not to because of possible confusion). (And the number 4.5.9 is already assigned
+to anonymous functions, so unless we dump those, so we had better identify that
+it is the AI12-0262-1 version.)
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent