Version 1.1 of ai12s/ai12-0262-1.txt

Unformatted version of ai12s/ai12-0262-1.txt version 1.1
Other versions for file ai12s/ai12-0262-1.txt

!standard 5.5.2(2/3)          18-03-01 AI12-0262-1/01
!standard 5.5.2(5/4)
!standard 5.5.2(7/3)
!class Amendment 18-03-01
!status work item 18-03-01
!status received 18-03-01
!priority Medium
!difficulty Hard
!subject Map/Reduce attribute
** TBD.
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 instance.]
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).
Static Semantics
Likely similar to the object version, but the elements come from a different place (logically).
Dynamic Semantics
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.)
** TBD.
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'"&", "") -- This is a terrible way to copy a string. :-) 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.
** Unknown.
!ACATS test
ACATS B- and C-Tests are needed to check that the new capabilities are supported.


Questions? Ask the ACAA Technical Agent