Overview of Ada 2022
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);
© 2021, 2022 Jeff Cousins