Version 1.1 of ai12s/ai12-0262-1.txt
!standard 5.5.2(2/3) 18-03-01 AI12-0262-1/01
!class Amendment 18-03-01
!status work item 18-03-01
!status received 18-03-01
!subject Map/Reduce attribute
AI12-0242-1 defines a reduction operation for existing objects. However,
in cases where there is no existing type that matches the objects to reduce,
this is less than convinient. Moreover, if the stream of objects to reduce
is indefinite, it isn't possible in Ada to declare an array type that matches
it. One could instantiate an indefinite container, but that would have to be
materialized (since it is made up of calls to user-defined operations).
What is needed is a way to directly process a stream of objects without
declaring a type and without forcing the materialization of an object.
[Author's note: I've just gathered a bunch of notes from public and private
e-mail discussion. These aren't complete.
One thing that is clear from discussions is that this "version" of the
Reduction attribute needs a separate description, as the name resolution,
legality rules, and dynamic semantics all have differences. Therefore, it
makes sense to put this into a separate AI, one that does depend on some
of the concepts defined in AI12-0242-1.]
(iterated_element_association)'Attribute_Designator (name, expression)
[Notes: "iterated_element_association" comes from AI12-0212-1. We're only
using the syntax here; the rest of the rules needs to be defined with this
AI. As a practical matter, the prefix would have to be parsed as if it is
an aggregate, and then checked that it has this form. (That's pretty common
for Ada constructs -- "name" often has to be parsed as "expression", for
The attribute designators are Reduce/Parallel_Reduce (or possibly
Reduction/Parallel_Reduction). [Should be the same as AI12-0242-1's choice.]
Name Resolution Rules
Expand the syntax above into it's parts, since we are concerned about doing
overload resolution on the parts of the iterator:
(for iterator => element_expr)'Reduction(combiner, initial-value)
A 'Reduction attribute reference is required to have a single expected type.
That then provides the expected type for the initial-value. We require the
first operand of the combiner (and the result if any) to have the type of
the initial-value. The second operand of the combiner has to have the type
of the element_expr.
For a combiner function, this makes the resolution problem look like:
X : expected_type := combiner(expected-type'(initial-value), element_expr);
...which is a pretty standard resolution problem. The iterator has to be
resolved without any context, of course (that's the usual case for iterators).
Likely similar to the object version, but the elements come from a different
We need to describe the operation of the operation directly in terms of the
iterator and interleaved invocations of the combiner. (And of course with
parallelism possibilities.) (The object'Reduction version uses the iterator
of the object for this task.)
It's mildly annoying that qualifying the prefix changes the resolution a lot
(as that turns the attribute into the object version (as in AI12-0242-1)).
My_String : String(1..10);
(for I in My_String'range => My_String(I))'Reduction (Standard'"&", "")
String'(for I in My_String'range => My_String(I))'Reduction (Standard'"&", "")
The first reduction overall requires a single expected type; it can't be used in a type
conversion, for instance. The type provided allows the rest of the reduction to resolve.
The second reduction requires the prefix to have a single expected type; that type
provides enough information to let the rest of reduction to resolve, and allow any
sort of use that can resolve.
Ultimately, however, these should do the same thing on a reasonable compiler;
there are permissions for the second to not materialize the prefix and allow
interleaving. The iterator that drives the first is the one explicitly given,
while the second is driven by the built-in iterator for array types. But these
ultimately are the same.
We can imagine cases where one would be legal and the other not legal, and
possibly cases where the semantics would be different in some subtle way, but
in general thinking of them as two views of the same construct will be fine
for anyone but Ada lawyers.
ACATS B- and C-Tests are needed to check that the new capabilities are
Questions? Ask the ACAA Technical Agent