AI22-0081-1
!standard 4.5.10(5/5) 24-03-23 AI22-0081-1/04
!standard 4.5.10(42/5)
!standard 4.5.10(44/5)
!standard 4.5.10(48/5)
!class Binding Interpretation 23-09-26
!status Corrigendum 1-2022 23-10-05
!status WG9 Approved 24-06-10
!status ARG Approved 12-0-0 23-10-05
!status work item 23-09-26
!status received 22-07-12
!priority Low
!difficulty Easy
!qualifier Omission
!subject Allow named notation for reduction expression arguments
See !subject .
Readability of reduction expressions could be improved by allowing the use of named notation in specifying the two arguments. Should this be allowed? (Yes.)
The names chosen for the two arguments are Reducer and Initial_Value. Named notation may be used to specify Initial_Value and Reducer, with the usual requirement that if the first argument uses named notation, then the second argument also must use named notation.
Replace 4.5.10(5/5) with:
reduction_specification ::= reducer_name, initial_value_expression
| [Reducer => ]reducer_name, Initial_Value => initial_value_expression
Replace 4.5.10(42/5) with:
-- See 3.5.7.
function Pi (Number_Of_Steps : Natural := 10_000) return Real is
(1.0 / Real (Number_Of_Steps) *
[for I in 1 .. Number_Of_Steps =>
(4.0 / (1.0 + ((Real (I) - 0.5) *
(1.0 / Real (Number_Of_Steps)))**2))]
'Reduce(Reducer => "+", Initial_Value => 0.0));
Modify 4.5.10(44/5):
A'Reduce("+",{ Initial_Value => }0) -- See 4.3.3.
Modify 4.5.10(48/5):
A'Parallel_Reduce({Reducer => }Integer'Min,
{
Initial_Value =>
}Integer'Last)
[Author’s note: The choices of examples to change are fairly arbitrary, but we do want to include at least one Parallel_Reduce example.]
Allowing (but not requiring) named notation is well accepted in many other contexts in Ada.
Not defining it for reduction expressions just seems like it was an oversight.
Like other attributes and pragmas, the parameters of these attributes cannot be reordered, even when named notation is used for all of them. Named notation only provides additional readability.
function Factorial(N : Natural) return Natural is
([for J in 1..N => J]'Reduce(Reducer => "*",
Initial_Value => 1));
@drepl
@xindent{@fa{reduction_specification}@fa{@ ::=@ }@i{reducer_}@fa{name},@ @i{initial_value_}@fa{expression}}
@dby
@xindent{@fa{reduction_specification}@fa{@ ::=@ }@i{reducer_}@fa{name},@ @i{initial_value_}@fa{expression}@hr
@ @ | @ @fa{[Reducer => ]}@i{reducer_}@fa{name}, @fa{Initial_Value => }@i{initial_value_}@fa{expression}}
@drepl
@xcode{-- @ft{@i{See 3.5.7.}}
@b{function} Pi (Number_Of_Steps : Natural := 10_000) @b{return} Real @b{is}
(1.0 / Real (Number_Of_Steps) *
[@b{for} I @b{in} 1 .. Number_Of_Steps =>
(4.0 / (1.0 + ((Real (I) - 0.5) *
(1.0 / Real (Number_Of_Steps)))**2))]
'Reduce("+", 0.0));}
@dby
@xcode{-- @ft{@i{See 3.5.7.}}
@b{function} Pi (Number_Of_Steps : Natural := 10_000) @b{return} Real @b{is}
(1.0 / Real (Number_Of_Steps) *
[@b{for} I @b{in} 1 .. Number_Of_Steps =>
(4.0 / (1.0 + ((Real (I) - 0.5) *
(1.0 / Real (Number_Of_Steps)))**2))]
'Reduce(Reducer => "+", Initial_Value => 0.0));}
@drepl
@xcode{A'Reduce("+",0) -- @ft{@i{See 4.3.3.}}}
@dby
@xcode{A'Reduce("+", Initial_Value => 0) -- @ft{@i{See 4.3.3.}}}
@drepl
@xcode{A'Parallel_Reduce(Integer'Min, Integer'Last)}
@dby
@xcode{A'Parallel_Reduce(Reducer => Integer'Min,
Initial_Value =>
Integer'Last)}
Some of the existing executable ACATS tests for reduction expressions could be modified to use named notation for some reduction expressions.
See issue #13 on ARG GitHub issue list.
!topic Reduction Expressions Attribute
!reference Ada 202x RM4.5.10(23/5)
!from Chrisoph Grein 2021-07-17
!keywords named parameter notation
!discussion
I've always liked the named parameter notation and use it always when it adds information like e.g. in Put (I, Width => 42), I hate to see calls like Put (X, 2, 3). I however use it never in cases where the actual and formal parameter have the same name - that's just noise - with one important exception: in cases like Arctan where calls with positional notation lose important information (here the coordinates, especially so as parameters are called y, x in this sequence).
To come to the point. Reduction expression are missing this feature and are less readable:
My_Rates'Reduce (Float'Min, Float'Last)
and I can easily dream up more cryptic expressions.
I'm very well aware of the problems: There is no way in Ada to use subprograms as parameters (only as access). What is more: Operators used in such expressions may be intrinsic, so they have not access.
So in the syntax proposed, there is a lot of magic involved. I know it's very (too?) late, but perhaps ARG ingenuity can come up with a solution. (I think there will be national ballots on the new RM, and I would raise this there.)
From: Tucker Taft
Sent: Saturday, July 17, 2021 9:22 AM
This comment will definitely be taken into account in the next revision. Alas, the 202X version has been finalized as of a few weeks ago, and making a similar comment during balloting on the new RM could actually delay the standard by six months. That is why we have gone through several rounds of public comments in advance of the finalization of the standard.
From: Christoph Grein
Sent: Monday, July 19, 2021 3:19 AM
I surely am not going to delay the new standard, which I think is just in time, 10 years after Ada 2012.
I've read the AI discussions and think ARG found a good solution (it's certainly more intuitive than the early proposals like for instance
(for I in 1 .. 10 => I**2)'Reduce(0 + <>)
which I find abominable).
From: Tucker Taft
Sent: Monday, July 19, 2021 9:03 AM
Actually the earlier version would have been:
(for I in 1 .. 10 => <0> + I**2)
but the current version is clearly easier for most folks to comprehend!
Adding names to the operands makes good sense, and is the kind of change that is easy to make after the fact because it is a pure extension and so completely upward compatible. It is also the kind of change that is easy for vendors to support in advance of a completely new standard, and so something we will consider in our upcoming post-Ada-202X ARG meetings, which will be starting this fall.