--- ai12s/ai12-0312-1.txt 2019/04/02 00:38:36 1.5 +++ ai12s/ai12-0312-1.txt 2019/04/02 00:45:54 1.6 @@ -1,4 +1,4 @@ -!standard 5.5.2(2/3) 19-03-22 AI12-0312-1/03 +!standard 5.5.2(2/3) 19-03-24 AI12-0312-1/04 !class presentation 19-02-07 !status work item 19-02-07 !status received 19-02-07 @@ -40,10 +40,10 @@ function To_Date (Value : String) return Date; function To_Date (Value : String) return Date is - declare + (declare S : constant String := Integer'Image (Integer'Value (Value)); - begin - ((Day => Integer'Value (S (S'Last-5 .. S'Last-4)), + begin + (Day => Integer'Value (S (S'Last-5 .. S'Last-4)), Year => Integer'Value (S (S'Last-3 .. S'Last)), Month => Month_Name'Val (Integer'Value (S (S'First .. S'Last-6))-1))); @@ -78,27 +78,29 @@ when 'M' => 1000); Append after 4.5.10 (53/5): - - A parallel reduction expression that outputs the mean of the - elements with even values for an array: - - type Accumulator is record - Sum : Integer; Addends : Natural; - end;= - - function Combine (L, R : Accumulator) return Accumulator is - (Sum => L.Sum + R.Sum, Addends => L.Addends + R.Addends); - - function Reduce (A : Accumulator; Addend : Integer) is - (Sum => A.Sum + Addend, Addends => A.Addends + 1); - - function Mean (A : Accumulator) return Integer is (A.Sum / A.Addends); - Put_Line("The mean of the even values of A is" & - Mean ([for Val of A when (A mod 2) = 0 => Val] - 'Parallel_Reduce(Reduce, - (Sum => 0, Addends => 0), - Combine))); + A parallel reduction expression used to calculate the mean of the + elements of a two dimensional array of subtype Matrix (see 3.6) that + are greater than 100.0: + + type Accumulator is record + Sum : Real; -- See 3.5.7 + Addend_Count : Integer; + end record; + + function Combine (L, R : Accumulator) return Accumulator is + (Sum => L.Sum + R.Sum, + Addend_Count => L.Addend_Count + R.Addend_Count); + + function Reduce (A : Accumulator; Addend : Real) return Accumulator is + (Sum => A.Sum + Addend, Addend_Count => A.Addend_Count + 1); + + function Average_of_Values_Greater_Than_100 (M : Matrix) return Real is + (declare Acc : constant Accumulator := + [for Val of M when Val > 100.0 => Val] + 'Parallel_Reduce(Reduce, (Sum => 0, Addends => 0), Combine); + begin + Acc.Sum / Real(Acc.Addend_Count)); Modify 5.5(22/5): @@ -200,6 +202,7 @@ defining sections for: - Conditional Expressions (4.5.7) +- Reduction Expressions using a Combiner (4.5.10) - Pre and Post conditions (6.1.1) - Global Aspect (6.1.2) - Type Invariants (7.3.2) @@ -207,24 +210,11 @@ - raise expressions and Predicate_Failure (11.3) - Image Attributes (4.10) - Variadic C functions (B.3) - -[Author Note: -- Stable Properties has a note 7.3.4 (24/5) that says, - "For an example of the use of these aspects, see the Vector container definition in A.18.2." - but currently no use of Stable_Properties exists there. Presumably this will be added as part of - AI12-0112-1.] -[Editor's note: See the draft 18 RM.] - - User Defined Literals (4.2.1) - Explicit Chunk definition for parallel loops (5.5) - implicit subtype mark in object renames (8.5.1) - null array aggregates (4.3.3) -For the Global aspect, a note was added to refer to the Vector Container -package for examples of use. At the time of writing, the Global aspects -had not yet been added to the containers. Presumably, this will happen, -and will provide some good examples. - The 'Image attribute has existed since Ada 83, but improved in Ada 202x, however it doesn't seem that an example is necessary. @@ -547,5 +537,112 @@ 3) It took me quite a time to spot the difference between "addend" and "addends". Using "count" instead of "addends" would help a lot... + +**************************************************************** + +From: Brad Moore +Sent: Sunday, March 24, 2019 2:20 PM + +> There are several glitches in the example that caused me quite a hard +> time understanding it... +> +> 1) +> Mean ([for Val of A when (A mod 2) = 0 => Val] +> "A mod 2" should be "Val mod 2", right? + +Thanks for catching this, Steve Baird also caught this. + +He also noted there was an extraneous "=" after the declaration of the +Accumulator type. + +> +> 2) +> In the above, A is some array whose declaration is not shown, while +> everywhere else, A is the accumulator. Please use a different name (and +> possibly show the declaration). + +The example was placed immediately after the following one in the RM, (4.5.10 +53/5) + +Calculate the sum of elements of an array of integers: + +A'Reduce("+",0) -- See 4.3.3. + +If you follow that reference you find the declaration of A, which is; + +type Table is array(1 .. 10) of Integer; + +A : Table := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0); + +That being said, this array is too small to likely be worth processing with a +parallel reduction expression, so I think the example needs to hint at +processing a much larger array. + +I decided to rework this example, to operate on the Matrix type defined in the +RM, which is an unconstrained array type of real. By making the example an +expression function, where the matrix is passed as a parameter, that will allow +a potentially very large array to be processed, without having to declare the +array in the RM. Since the type of the sum is now Real, instead of Integer, the +iterator filter should be something like filtering out all values <= 100.0, +rather than even numbers, which is probably a more realistic filter anyway. + +There also were a couple of other glitches in the AI, which I noticed, making a +better case for submitting an new update, which I have done below. + +- The Accumulator type is missing "record" after end, i.e. "end record;" +- The function Reduce doesn't specify what it is returning +- The expression function, To_Date for an earlier example in the AI Appended + after 4.2.1(10/5) has the first opening paren after the declare of the + declare expression, instead of before. +- In the discussion section there are some comments about missing aspect + examples ('Global and 'Stable_Properties) that have since been added to + the RM draft, so those comments are no longer needed. It also needs to + mention that we were missing an example of a reduction expression + using a Combiner. + +> 3) +> It took me quite a time to spot the difference between "addend" and +> "addends". Using "count" instead of "addends" would help a lot... + +I agree that is pretty subtle, but I also find Count is perhaps too vague, +and doesn't describe what we are counting. So I would use Addend_Count instead, +which seems to address your comment, as well as my own. + +Here is a new version of the AI after these updates. + +Note that I got rid of the Mean function, since the new expression function +incorporates the mean. I also used a declare expression in the expression +function which does the parallel reduction. + +Here is the updated example for the AI + + + A parallel reduction expression used to calculate the mean of the + elements of a two dimensional array of subtype Matrix (see 3.6) that + are greater than 100.0: + + type Accumulator is record + Sum : Real; -- See 3.5.7 + Addend_Count : Integer; + end record; + + function Combine (L, R : Accumulator) return Accumulator is + (Sum => L.Sum + R.Sum, + Addend_Count => L.Addend_Count + R.Addend_Count); + + function Reduce (A : Accumulator; Addend : Real) return Accumulator is + (Sum => A.Sum + Addend, Addend_Count => A.Addend_Count + 1); + + function Average_of_Values_Greater_Than_100 (M : Matrix) return Real is + (declare Acc : constant Accumulator := + [for Val of M when Val > 100.0 => Val] + 'Parallel_Reduce(Reduce, (Sum => 0, Addends => 0), Combine); + begin + Acc.Sum / Real(Acc.Addend_Count)); + + +And here is the full updated AI, which the changes described above; + +[This is version /04 of the AI - Editor.] ****************************************************************

Questions? Ask the ACAA Technical Agent