Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
Overview of Ada 2022
Jeff Cousins
Contents   Index   Search   Previous   Next 

2.5 Reduction

Reduction expressions are another new form of expression, added by Ada 2022, on top of those already added by Ada 2012 (e.g. if expressions, case expressions, quantified expressions). Before the parallel forms can be described, the sequential forms have to be described. These make use of Container aggregates; generalized array aggregates (AI12-0212) (see 4.5), which in turn makes use of Index parameters in array aggregates (AI12-0061) (see 7.4), so first a preview of them.
Index parameters in array aggregates (AI12-0061) allows a loop parameter to be used in an array aggregate, for example:
subtype Index_Type is Positive range 1 .. 10;
type Array_Type is array (Index_Type) of Positive;
Squares_Array : Array_Type := (for I in Index_Type => I * I);
Container aggregates; generalized array aggregates (AI12-0212) introduces container aggregates for initialising containers, using square brackets not round brackets (parentheses), and allowing square brackets as an alternative to round brackets for array aggregates.
Iteration is possible within the container aggregate, for example to create a set whose elements all have double the value of the corresponding elements of another set:
Doubles_Set : My_Set := [ for Item of X => Item * 2 ];
Map-Reduce attribute (AI12-0262) provides a mechanism (see RM 4.5.10) to take a stream of values – a “value sequence” – from an aggregate, and repeatedly apply the same operation to combine the values to produce a single result. Examples include adding a sequence of squares for “sum of squares” or multiplying a sequence of numbers when calculating a factorial. An initial value is required, usually something neutral that has no effect on the result, such as 0 for addition or 1 for multiplication. A parallel version is provided, though if the combining operation is something simple such as addition then the overhead of managing the parallelism is likely to outweigh any performance benefit of performing the additions in parallel. Some examples:
-- A reduction expression that outputs the sum of squares
Put_Line ("Sum of Squares is" & Integer'Image
   ([ for I in 1 .. 10 => I**2 ]'Reduce("+", 0));
-- An expression function that returns its result as
-- a Reduction Expression
function Factorial (N : Natural) return Natural is
   ([ parallel for J in 1..N => J ]'Reduce("*", 1));
It is important to note that the values are not put in some temporary array then combined, but are combined “on the fly” as each value is produced.
Shorthand Reduction Expressions for Objects (AI12-0242) provides a shorthand for cases where the object is an array or iterable container. For example:
Sum : constant Integer := A'Reduce("+", 0);
is short for:
Sum : constant Integer :=
        [ for Value of A => Value ]'Reduce("+", 0);
Sum : constant Integer := A'Parallel_Reduce("+", 0);
is short for:
Sum : constant Integer :=
        [ parallel for Value of A => Value ]'Reduce("+", 0);

Contents   Index   Search   Previous   Next 
© 2021, 2022 Jeff Cousins