Version 1.12 of ai12s/ai12-0127-1.txt

Unformatted version of ai12s/ai12-0127-1.txt version 1.12
Other versions for file ai12s/ai12-0127-1.txt

!standard 4.3(2)          16-10-06 AI12-0127-1/06
!standard 4.3(4)
!standard 4.3.3(3)
!standard 4.3.4(0)
!standard 7.5(2.10/3)
!class Amendment 14-08-21
!status work item 14-08-21
!status received 14-07-14
!priority Medium
!difficulty Hard
!subject Partial aggregate notation
!summary
A notation for updating part of a composite type is defined (where the remainder of the type is unchanged).
!problem
It is common to need to use an object of a composite type with just a small modification (often of a single component). This can be awkward to express in Ada.
For instance, consider a record type Rec with many components, one of which is Colour, a variable R of type Rec, and the need to call procedure Foo with R but using the Black colour.
There are two ways to do this in current Ada, but both are ugly. The first uses a temporary variable, a copy, and an assignment to the component:
declare T : Rec := R; begin T.Colour := Black; Foo (T); end;
The other way uses an aggregate listing all components of Rec, which is very cumbersome and a burden for maintenance:
Foo ((X => R.X, Y => R.Y, ...., Colour => Black));
This construct is especially common in postconditions. It's common for a subprogram only to change a small part of a large composite type.
procedure Foo (Fighters : in out Rec) with Post => (Fighters.Colour = Black and Fighters = (X => Fighters'Old.X, Y => Fighters'Old.Y, ... Shape => Trapazoid));
This is cumbersome enough that the Postcondition author might check the changed component and not even mention that the other components are unchanged.
Some better way to write these should be provided.
[Editor's note: Sorry, these identifiers reminded me of the title of one of my favorite albums of all time. It should be pretty obvious (at least after a visit to Wikipedia); I would have liked to work in the two "the"s but that was over the top.]
!proposal
(See wording.)
!wording
Replace 4.3(2):
aggregate ::= record_aggregate | extension_aggregate | array_aggregate
with:
aggregate ::= record_aggregate | extension_aggregate | array_aggregate | delta_aggregate
Replace 4.3(4):
An aggregate shall not be of a class-wide type.
with:
A record aggregate or extension aggregate shall not be of a class-wide type.
[Author's note: We re-factor the definition of named_array_aggregate so we can re-use it later.]
Replace 4.3.3(3):
named_array_aggregate ::= (array_component_association {, array_component_association})
with:
named_array_aggregate ::= ( array_component_association_list )
array_component_association_list ::= array_component_association {, array_component_association}
Add a new subclause:
4.3.4 Delta Aggregates
A (record or array) delta aggregate yields a composite value resulting from starting with another value of the same type and then subsequently assigning to some (but typically not all) components of the copy.
Syntax
delta_aggregate ::= record_delta_aggregate | array_delta_aggregate
record_delta_aggregate ::= (*base_*expression with delta record_component_association_list)
array_delta_aggregate ::= (*base_*expression with delta array_component_association_list)
Name Resolution Rules
The expected type for a record_delta_aggregate shall be a single record type or record extension.
The expected type for an array_delta_aggregate shall be a single array type.
The expected type for the base_expression of any delta_aggregate is the type of the enclosing delta_aggregate.
For a record_delta_aggregate, the expected type and applicable index constraint of the expression in each record_component_association is defined as for a record_component_association occurring within a record aggregate.
For an array_delta_aggregates, the expected type for each discrete_choice in an array_component_association is the index type of type of the delta aggregate.
The expected type and applicable index constraint of the expression in array_component_association is defined as for an array_component_association occurring within an array aggregate of the type of the delta aggregate.
Legality Rules
For a record_delta_aggregate, the record_component_association_list shall not be null record, the record_component_association shall not use the box symbol <>, and the component_choice_list shall not use others.
For a record_delta_aggregate, each component_selector_name of each component_choice_list shall denote a distinct non discriminant component of the type of the delta aggregate.
The types of components in record_component_associations follow the same rules as they do for record aggregates (see 4.3.1).
For an array_delta_aggregate, the array_component_association shall not use the box symbol <>, and the discrete_choice shall not be others.
For an array_delta_aggregate, the dimensionality of the type of the delta aggregate shall be 1.
For a delta_aggregate the expression in a record_component_association or a array_component_association shall not be of a limited type.
For an array_delta_aggregate, the base_expression shall be of a nonlimited type.
AARM Ramification: The base_expression of a record_delta_aggregate may be of a limited type (for example a record with limited components), the above rule only makes sure we do not assign to a limited component. We do not allow the base_expression of an array_delta_aggregate to be of a limited type as this is a useless construct (you would not be able to update anything as the components necessarily are also limited except in pathological cases).
Dynamic Semantics
The evaluation of a delta_aggregate begins with evaluating the base_expression of the delta_aggregate and using that value to create and initialize the aggregate's anonymous object.
AARM Discussion: This follows the same rules as for initializing the object denoted by 'Old (see 6.1.1) except in the case where the anonymous object is built in place (see 7.6).
Next, for each component for which an expression is provided, the expression is evaluated and assigned to that component of the object. In the case of an array component, the associated index expression is also evaluated and used in determining the target component just as in any array indexing operation. As with any aggregate, evaluation of a delta_aggregate then denotes the associated anonymous object.
AARM Ramification: As with 'Old, this means that the underlying tag (if any) associated with the delta aggregate is that of the expression in delta_aggregate and not that of the nominal type of the expression in delta_aggregate.
AARM To Be Honest: The anonymous object associated with the evaluation of a delta aggregate begins its life as a variable, not a constant (Ada RM 3.3 notwithstanding). This must be the case because the object is initialized and then subsequently modified. After evaluation of the delta aggregate is complete, the object is a constant object. This is similar to the way that an extended return statement can provide a variable view of an object that will eventually be a constant object after the function returns its result via "build in place".
For a record_delta_aggregate, the order of the subsequent assignments is unspecified. For an array_delta_aggregate, the subsequent assignments (including all associated expression evaluations) are performed in the order in which the array_component_association_list is given; within a single array_component_association, in the order of the discrete_choice_list; and within the range of a single discrete_choice, in ascending order.
Examples
Simple use in a postcondition:
procedure Twelfth (D : in out Date) -- see 3.8 for type Date with Post => D = (D'Old with delta Day => 12);
procedure The_Answer (V : in out Vector; A, B : in Integer) -- see 3.6 for type Vector with Post => V = (V'Old with delta A .. B => 42.0, V'First => 0.0);
The base expression can be non-trivial:
New_Cell : Cell := Min_Cell (Link) with delta Value => 42); -- see 3.10.1 for Cell and Link; 6.1 for Min_Cell
A1 : Vector := ((1, 2, 3) with delta Integer (Random * 3.0) => 14.2); -- see 3.6 for declaration of type Vector -- see 6.1 for declaration of Random
Tomorrow := ((Yesterday with delta Day => 12) with delta Month => Apr); -- see 3.8
The base expression may also be class-wide:
function Translate (P : Point'Class; X, Y : Float) return Point'Class is (P with delta X => P.X + X, Y => P.Y + Y); -- see 3.9 for declaration of type Point
Add after 7.5(2.10/3):
* the *base_*expression of a record_delta_aggregate (see 4.3.4)
!discussion
SPARK 2014 defines an attribute Update for this purpose. Using this attribute, the call in the question can be expressed as:
Foo (R'Update (Color => Black));
We believe it is better to use aggregate syntax for this, as we certainly want aggregate semantics relative to temporaries, build-in-place, limited types, resolution, and the like to apply. Additionally, by using aggregate notation, we can reuse some of the existing definitions for aggregate elements.
Multi-dimensional array aggregates ----------------------------------
This will be a separate AI.
Discriminants ------------- Should we allow discriminants in record updates?
We decided "No".
They would have to be listed first, and require any variant section to be completely updated. (Indeed, all discriminant-dependent components would have to be present.)
!examples
Using this facility, the initial example in the !problem can be written:
Foo ((R with delta Colour => Black));
The postcondition example can be written as:
procedure Foo (Fighters : in out Rec) with Post => (Fighters.Colour = Black and Fighters = (Fighters'Old with delta Shape => Trapazoid));
Also see the examples in the !wording section.
!ASIS
No ASIS impact.
!ACATS test
ACATS B-Tests and C-Tests are needed to test the implementation of this feature.
!appendix

topic        Adding partial aggregate functionality to Ada
!reference    Ada 2012 RM{clause unsure}
!from        Simon Clubley 2014-07-13
!keywords    partial aggregate device register bitfields atomic updating

[The original motivation for this proposal was the simultaneous updating of
multiple bitfields in a device register. However, discussions in comp.lang.ada
have revealed a wide range of potential uses for this notation which would allow
these other existing uses to be expressed more cleanly. The examples
demonstrating the wider potential of this proposal were provided by Niklas
Holsti.]

Background
----------
Ada can model the bitfields in a device register as a record type containing
those bitfields and can map an instance of that record type to the address of
that device register.

However, sometimes there is a requirement to be able to update a subset of those
bitfields as an atomic operation while preserving the contents of the other
bitfields in the record.

In Ada, the only way to do this (apart from C style bitmasks on an integer
variable) is to read the device register into a temporary instance of the record
type, modify the temporary variable and write the temporary variable back to the
device register.

This, to put it mildly, is ugly.

Normal (non-atomic) records also have similar issues.

For normal records, consider a record type Rec with many components, one of
which is Colour, a variable R of type Rec, and the need to call procedure Foo
twice, once using R with its own Colour, and once with R but using the Black
colour.

There are two ways to do this in current Ada, but both are ugly. The first uses
a temporary variable, a copy, and an assignment to the component:

   declare
      T : Rec := R;
   begin
      Foo (R);
      T.Colour := Black;
      Foo (T);
   end;

The other way uses an aggregate listing all components of Rec, which is very
cumbersome and a burden for maintenance:

   Foo (R);
   Foo ((X => R.X, Y => R.Y, ...., Colour => Black));

Proposal
--------
An elegant solution for these problems would be a new partial aggregate syntax
in which the list of record components to be modified would be listed along with
their new values.

One suggested syntax would be:

    A := (A changing C => D, E => F);

or

    A := (A updating C => D, E => F);

where A is a record and C and E are record components.

[When this syntax discussion took place in comp.lang.ada, one suggestion for the
keyword was "overriding" but I didn't like that because that keyword made it
seem as if A was the one doing the overriding, not the later C and E
references.]

For an Atomic record, the compiler would generate a sequence which performs an
atomic read of the whole record into a compiler generated temporary, modifies
this temporary with the new component values, then performs an atomic write of
this temporary back to the whole record.

As the sequence would be performed on the record as a whole, C.6(15) would be
guaranteed to apply. This means there would be a single read of the device
register and a single write to the device register.

For the normal record example above, one could simply write instead

   Foo (R);
   Foo ((R changing Colour => Black));

which is much more elegant than the above methods currently provided by Ada.

In addition, Niklas also provided the following array aggregate example:

   type Month_Days is array (Month) of Positive;

   Normal_Year_Days : constant Month_Days :=
      (Jan => 31, Feb => 28, Mar => 31, ..., Dec => 31);

   Leap_Year_Days : constant Month_Days :=
      (Normal_Year_Days changing Feb => 29);

It was also suggested partial aggregates could be of use in contracts within Ada
2012 and also had some uses within SPARK. However, this is one area I currently
have no experience with, so I reproduce the following example as-is:

|I have not yet used Ada 2012 contracts in my programming, but I believe
|that partial aggregates would be quite useful in post-conditions, to
|express that some "out" value is the same as some "in" value except for
|changes to certain components:
|
|   with Post => X = (X'old changing Colour => Black)

Regarding the use of a new keyword, I do think we need a new keyword because we
are talking about adding a subset update capability to Ada and that new usage
should stand out in any code.

****************************************************************

From: Tucker Taft
Sent: Tuesday, July 15, 2014  11:49 AM

Interestingly, SPARK 2014 has a capability almost exactly matching this, using
an attribute "'Update"; for example:

    T : Rec := R'Update (Colour => Black);

or

    Foo (R'Update (Colour => Black));

I believe this attribute is also available in recent releases of GNAT, though
clearly at this stage it is non portable.

****************************************************************

From: Tucker Taft
Sent: Tuesday, July 15, 2014   5:46 PM

Steve Baird had told me about this attribute in Paris. One thing almost everyone
I've talked to about it agrees is that this is a hack as an attribute -- this is
a kind of aggregate and ought to look like it.

Attributes are supposed to be kinds of function calls, but it's not possible to
write this Update attribute as a function call. Moreover, we would want all of
the aggregate rules to apply to the contents, and there aren't function calls
like:
    R'Update (Primary_Color => True); -- Primary_Color is a subtype with a static predicate or
    R'Update (1..5 => True);

Most likely, we'd want the aggregate rules to apply to the result, as well
(build-in-place, etc. -- but here at least a function call is consistent with
aggregates).

SPARK had to make this an attribute because they couldn't add new syntax.
That's no reason for Ada itself to limit itself in such a way. (As one Tucker
Taft has said in the past, new features shouldn't look "bolted-on", and I can't
imagine a worse "bolt-on" than using an attribute with aggregate semantics
instead of a proper aggregate.)

Ergo, this phony attribute should stay a SPARK-only thing; Ada needs a proper
aggregate syntax for this.

****************************************************************

From: Simon Clubley
Sent: Wednesday, July 16, 2014  4:25 PM

> Interestingly, SPARK 2014 has a capability almost exactly matching
> this, using an attribute "'Update"; for example:
>
>     T : Rec := R'Update (Colour => Black);
>
> or
>
>     Foo (R'Update (Colour => Black));
>
> I believe this attribute is also available in recent releases of
> GNAT, though clearly at this stage it is non portable.

Thanks. Yes, it is in GNAT. I did notice

   http://gcc.gnu.org/onlinedocs/gnat_rm/Attribute-Update.html

is silent about if C.6(15) is guaranteed to apply when R (in your
example) is Atomic.

> Steve Baird had told me about this attribute in Paris. One thing
> almost everyone I've talked to about it agrees is that this is a hack
> as an attribute -- this is a kind of aggregate and ought to look like it.

I agree with this; I think a "real" partial aggregate syntax is required.

Are there any thoughts on how the proposed syntax could be improved ?

> Ergo, this phony attribute should stay a SPARK-only thing; Ada needs a
> proper aggregate syntax for this.

Is there support here for adding partial aggregates to the next version of Ada?

When combined with an Atomic record, such syntax would allow the simultaneous
updating of multiple bitfields within a record mapped to a device register. It
would also be useful in a more general way as shown by the examples provided in
comp.lang.ada and reproduced in my submission.

****************************************************************

From: Steve Baird
Sent: Tuesday, July 22, 2014  12:41 PM

> I think a "real" partial aggregate syntax is required.
> Are there any thoughts on how the proposed syntax could be improved ?

Randy and I have discussed the possibility of using extension aggregate syntax
except using "with delta" in place of "with".

Given
    type T is record F1, F2, F3, F4 : Integer; end record;
    X : T;
and then taking this approach
    X'Update (F3 => 123, F4 => 456);
could be expressed as
    (X with delta F3 => 123, F4 => 456);

At this point this is nothing more than an idea that came up in conversation.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, July 22, 2014  1:08 PM

But of course one that will be included in the AI associated with this thread.
So the idea will at least be on the radar.

****************************************************************

From: Mark Lorenzen
Sent: Wednesday, July 23, 2014  4:12 AM

> I agree with this; I think a "real" partial aggregate syntax is
> required.
>
> Are there any thoughts on how the proposed syntax could be improved ?

It could maybe be done as for an extension aggregate, unless that would confuse
users:

Foo (R with Colour => Black);

or

S := (R with Colour => Black);

****************************************************************

From: Simon Clubley
Sent: Wednesday, July 23, 2014  3:05 PM

> Randy and I have discussed the possibility of using extension
> aggregate syntax except using "with delta" in place of "with".
>
> Given
>     type T is record F1, F2, F3, F4 : Integer; end record;
>     X : T;
> and then taking this approach
>     X'Update (F3 => 123, F4 => 456);
> could be expressed as
>     (X with delta F3 => 123, F4 => 456);

I don't like the idea of seeing just the exact same "with" extension aggregate
notation re-used for partial aggregates as I think that would be too confusing.

However, while I think new syntax such as "changing" would be best, if the
desire is to re-use existing keywords, then I think your "with delta" suggestion
is by far the best of the suggestions I have seen so far and would not be
confused with an extension aggregate.

****************************************************************

From: Christoph Grein
Sent: Thursday, July 24, 2014  5:13 AM

The problem with these two reserved words
    F (X with delta F3 => 123, F4 => 456);
is that one might easily forget the delta and, with some overloading of F, might
arrive at a different legal interpretation.

****************************************************************

From: Tucker Taft
Sent: Sunday, July 27, 2014  3:23 PM

Somewhat unlikely because Ada requires that there be a unique interpretation
provided by context before looking inside an aggregate.

****************************************************************

From: Steve Baird
Sent: Saturday, June 27, 2015  9:17 AM

The Update attribute provides a way of overwriting specified components of a
copy of a given composite value.

For a prefix ``X`` that denotes an object of a nonlimited record type or record
extension ``T``, the attribute

::

      X'Update ( record_component_association_list )

is defined and yields a value of type ``T`` and is a *record update expression*.

For a prefix ``X`` that denotes an object of a nonlimited one dimensional array
type ``T``, the attribute

::

      X'Update ( array_component_association {, array_component_association} )

is defined and yields a value of type ``T`` and is an *array update expression*.

For a prefix ``X`` that denotes an object of a nonlimited multidimensional
array type ``T``, the attribute

::

     X'Update ( multidimensional_array_component_association
             {, multidimensional_array_component_association} )

is defined and yields a value of type ``T`` and is a *multi-dimensional array
update*.  Where ``multidimensional_array_component_association`` has the following
syntax:

.. centered:: **Syntax**

::

   multidimensional_array_component_association ::=
     index_expression_list_list => expression
   index_expression_list_list ::=
     index_expression_list { | index_expression_list }
   index_expression_list ::=
     ( expression {, expression} )

.. centered:: **Legality Rules**

1. The box symbol, <>, may not appear in any ``expression`` appearing
    in an *update expression*.

.. centered:: **Dynamic Semantics**


2. In all cases (i.e., whether ``T`` is a record type, a record
    extension type, or an array type - see below), evaluation of
    ``X'Update`` begins with the creation of an anonymous object of
    type ``T`` which is initialized to the value of ``X`` in the same
    way as for an occurrence of ``X'Old`` (except that the object is
    constrained by its initial value but not constant).


3. Next, components of this object are updated as described in the
    following subsections. The attribute reference then denotes a
    constant view of this updated object. The master and accessibility
    level of this object are defined as for the anonymous object of an
    aggregate.

4. The assignments to components of the result object described in the
    following subsections are assignment operations and include
    performance of any checks associated with evaluation of the target
    component name or with implicit conversion of the source value to
    the component subtype.


Record Update Expressions
^^^^^^^^^^^^^^^^^^^^^^^^^

For a record update expression of type ``T`` the following are required.

.. centered:: **Legality Rules**


5. The ``record_component_association_list`` shall have one or more
    ``record_component_associations``, each of which shall have a
    non-**others** ``component_choice_list`` and an expression.


6. Each ``selector_name`` of each ``record_component_name`` shall denote a
    distinct non discriminant component of ``T``.


7. Each ``record_component_association``'s associated components shall
    all be of the same type. The expected type and applicable index
    constraint of the expression is defined as for a
    ``record_component_association`` occurring within a record
    aggregate.


8. Each selector of all ``component_choice_lists`` of a record
    update expression shall denote a distinct component.



.. centered:: **Dynamic Semantics**


9. For each component for which an expression is provided, the
    expression value is assigned to the corresponding component of the
    result object. The order in which the components are updated is
    unspecified.

[Components in a record update expression must be distinct.  The following is
illegal

::

   Some_Record'Update
     (Field_1 => ... ,
      Field_2 => ... ,
      Field_1 => ... ); -- illegal; components not distinct

because the order of component updates is unspecified.]

Array Update Expressions
^^^^^^^^^^^^^^^^^^^^^^^^^

For an array update expression of type ``T`` the following are required.

.. centered:: **Legality Rules**


10. Each ``array_component_association`` of the attribute reference
     shall have one or more ``array_component_associations``, each of
     which shall have an expression.

11. The expected type and applicable index constraint of the
     expression is defined as for an ``array_component_association``
     occurring within an array aggregate of type ``T``. The expected
     type for each ``discrete_choice`` is the index type of ``T``.


12. The reserved word **others** shall not occur as a
     ``discrete_choice`` of an ``array_component_association`` of the
     ``attribute_reference``.


.. centered:: **Dynamic Semantics**


13. The discrete choices and array component expressions are
     evaluated. Each array component expression is evaluated once for
     each associated component, as for an array aggregate. For each
     such associated component of the result object, the expression
     value is assigned to the component.


14. Evaluations and updates are performed in the order in which the
     ``array_component_associations`` are given; within a single
     ``array_component_association``, in the order of the
     ``discrete_choice_list``; and within the range of a single
     ``discrete_choice``, in ascending order.


[Note: the ``Update`` attribute for an array object allows multiple
assignments to the same component, as in either

::

   Some_Array'Update (1 .. 10 => True, 5 => False)

or

::

   Some_Array'Update (Param_1'Range => True, Param_2'Range => False)
   -- ok even if the two ranges overlap]

Multi-dimensional Array Update Expressions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For a multi-dimensional array update expression of type ``T`` the following are required.

.. centered:: **Legality Rules**

15. The expected type and applicable index constraint of the
     expression of a ``multidimensional_array_component_association``
     are defined as for the expression of an
     ``array_component_association`` occurring within an array
     aggregate of type ``T``.


16. The length of each ``index_expression_list`` shall equal the
     dimensionality of ``T``. The expected type for each expression in
     an ``index_expression_list`` is the corresponding index type of
     ``T``.

.. centered:: **Dynamic Semantics**


17. For each ``multidimensional_array_component`` association (in the
     order in which they are given) and for each
     ``index_expression_list`` (in the order in which they are given),
     the index values of the ``index_expression_list`` and the
     expression are evaluated (in unspecified order) and the expression
     value is assigned to the component of the result object indexed by
     the given index values. Each array component expression is
     evaluated once for each associated ``index_expression_list``.

****************************************************************

From: Florian Schanda
Sent: Monday, June 6, 2016  8:38 AM

This AI is part of my (overdue) Pisa homework. I have worked on this with the
help of Steve. It should be concrete enough so that we have something to
discuss.

[This is version /02 of the AI - Ed.]

****************************************************************

From: Bob Duff
Sent: Monday, June 6, 2016  12:14 PM

> A (record, array, multidimensional) delta aggregate yields a composite 
> value resulting from copying another value of the same type and then 
> subsequently assigning to some (but typically not all) components of 
> the copy.

I like this feature.  I don't much like the keyword "delta"; seems contrived.
But I suppose I won't complain too loudly about that.  "update" is probably
way too incompatible. Unless we (again) try to go the "unreserved keyword"
route.
E.g.:

    (X update with ...)

>   index_tuple ::= ( expression {, expression} )

There seems to be a syntactic ambiguity here.  Is this:

    X := (X with delta (1) => Y);

an array delta aggregate or a multidimensional delta aggregate?
Seems like you want:

    index_tuple ::= ( expression, expression {, expression} )

> ** Name Resolution Rules **
> 
> The type of a delta aggregate is the same as the type of the 
> expression in delta_aggregate.

I think you want the type to come from context, like other aggregates.
Then that type becomes the expected type for the expression.

> For an array delta aggregate, the dimensionality of the type of the 
> delta aggregate shall be 1; for a multidimensional delta aggregate the 
> dimensionality of the type of the delta aggregate shall more than 1.

Here's a place where the above-mentioned ambiguity comes into play.

> Ranges in multidimensional updates
> ----------------------------------
> 
> This is a proposal to allow more helpful (but slightly more complex) 
> multidimensional delta aggregates. It is presented as a modification 
> to the above !wording section.

I'd leave this functionality out.

****************************************************************

From: Randy Brukardt
Sent: Monday, June 6, 2016  11:42 PM

> This AI is part of my (overdue) Pisa homework. I have worked 
> on this with the help of Steve. It should be concrete enough 
> so that we have something to discuss.

I suppose we should know better than to pair the new guy with Steve; Steve
makes me work more than anyone else to construct a complete AI out of pieces.

Anyway, I reformatted the submission to make it fit the standard AI format;
the discussion is light and the name of the new feature switches back and
forth between "partial aggregate" (the name in the first draft) and "delta
aggregate" (the name in the second draft). Issues that can be fixed, but
probably don't matter if there are major problems with this (not that I see
any).

****************************************************************

From: Steve Baird
Sent: Tuesday, June 7, 2016  2:32 AM

>> For an array delta aggregate, the dimensionality of the type of the 
>> delta
>> >aggregate shall be 1; for a multidimensional delta aggregate the 
>> >dimensionality of the type of the delta aggregate shall more than 1.
> Here's a place where the above-mentioned ambiguity comes into play.
>

I'd say that's the place where the ambiguity is resolved.

But I agree that your proposed syntax change is an improvement and with that
change there is no ambiguity to even discuss.

> I think you want the type to come from context, like other aggregates.
> Then that type becomes the expected type for the expression.

Interesting question. Given that we didn't modify 4.3(3/2), I agree with you.
But we could modify that rule.

Do we want to allow

      type T is new String;
      procedure P (X : String) is ... ;
      procedure P (X : T) is ... ;
      Y : String := ... ;
   begin
      P (X => (Y with delta ...));

? Probably not, so 4.3(3/2) is left unmodified and I agree with your proposed change.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, June 7, 2016  5:02 PM

I've applied these two changes into the working draft of the AI (so we don't
have to waste meeting time discussing them).

I changed the Name Resolution Rule in A.3.4 as follows (copying A.3.2 as
closely as possible):

   The expected type for a delta_aggregate shall be a single array type, record
   type, or record extension. The expected type for the *base_*expression 
   is the type of the enclosing delta_aggregate.

Note that I gave the first expression in the aggregate a prefix so it can't be
confused with any of the others:
  delta_aggregate ::= (*base_*expression with delta delta_aggregate_association)

We may want to come up with a better prefix for this.

The next paragraph doesn't make any sense as written:

The expected type for expression in a delta_aggregate depends on which form of
delta_aggregate_association is used: a record type for
record_component_association_list, and an array type for
array_component_association_list or
multidimensional_array_component_association_list.

The *base_*expression's type doesn't depend on that at all, and there is no
other expression (directly) in the syntax of a delta_aggregate. The way
expressions in component_associations are interpreted depends on those
component associations, but that is already defined in 4.3.1 and 4.3.3 (to the
extent that you reuse those, hopefully a lot).

Indeed, I'd only mention the types for the new kind of association, the
multidimensional_array_component_association. The others are defined where
they're declared, repeating wording here is only going to introduce conflicts.

(I didn't make that change in the draft, it needs discussion.)

****************************************************************

From: Tucker Taft
Sent: Tuesday, June 7, 2016  5:16 PM

I agree with your points here Randy.  I had the same concerns with some of the
wording.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, June 7, 2016  5:40 PM

...
> The next paragraph doesn't make any sense as written:
> 
> The expected type for expression in a delta_aggregate depends on which 
> form of delta_aggregate_association is used: a record type for 
> record_component_association_list, and an array type for 
> array_component_association_list or 
> multidimensional_array_component_association_list.

It strikes me that there needs to be a Legality Rule that prevents a record
from having array components and vice versa. But we surely wouldn't want to
get that tangled into resolution. Resolution is hard enough as it is, and we
don't want to make it too smart.

The Legality Rule could be:

If the delta_aggregate contains a record_component_association_list, the type
of the *base_*expression shall be a record type. Similarly, if the
delta_aggregate contains an array_component_association_list or
multidimensional_array_component_list, the type of the *base_*expression shall
be an array type.

Perhaps this could be combined with some of the other Legality Rules.

****************************************************************

From: Bob Duff
Sent: Tuesday, June 7, 2016  6:03 PM

> >> For an array delta aggregate, the dimensionality of the type of the 
> >> delta
> >> >aggregate shall be 1; for a multidimensional delta aggregate the 
> >> >dimensionality of the type of the delta aggregate shall more than 1.
> > Here's a place where the above-mentioned ambiguity comes into play.
> >
> 
> I'd say that's the place where the ambiguity is resolved.

No, that's not marked as a Name Resolution rule.  Just Legality.
So it can't be used to resolve syntactic ambiguities.

> But I agree that your proposed syntax change is an improvement and 
> with that change there is no ambiguity to even discuss.

OK.

> > I think you want the type to come from context, like other aggregates.
> > Then that type becomes the expected type for the expression.
> 
> Interesting question. Given that we didn't modify 4.3(3/2), I agree 
> with you. But we could modify that rule.
> 
> Do we want to allow
> 
>       type T is new String;
>       procedure P (X : String) is ... ;
>       procedure P (X : T) is ... ;
>       Y : String := ... ;
>    begin
>       P (X => (Y with delta ...));

No.  Resolution rules should be weak.

> ? Probably not, so 4.3(3/2) is left unmodified and I agree with your 
> proposed change.

****************************************************************

From: Steve Baird
Sent: Wednesday, June 8, 2016  5:58 AM

> It strikes me that there needs to be a Legality Rule that prevents a 
> record from having array components and vice versa

We already have name resolution rules like

    4.3.1 - The expected type for a record_aggregate shall be a single
   record type or record extension.

    4.3.2 - The expected type for an extension_aggregate shall be a
    single type that is a record extension.

    4.3.3 - The expected type for an array_aggregate (that is not a
    subaggregate) shall be a single array type

Would it be more consistent to have name resolution rules (as opposed to
legality rules) which specify that the expected type of a delta_aggregate
is a single record type or record extension if the
delta_aggregate_association is a record_component_association_list and
a single array type otherwise ?

****************************************************************

From: Tucker Taft
Sent: Wednesday, June 8, 2016  6:05 AM

I think you might have it backwards.  The expected type for an aggregate comes
first, then you indicate what is allowed inside.  There is a fundamental rule
with aggregates that you don't look "inside" until you know what is the type
of the aggregate.

****************************************************************

From: Bob Duff
Sent: Wednesday, June 8, 2016  6:05 AM

> Would it be more consistent to have name resolution rules (as opposed 
> to legality rules) which specify that the expected type of a 
> delta_aggregate is a single record type or record extension if the 
> delta_aggregate_association is a record_component_association_list and 
> a single array type otherwise ?

Maybe have separate syntax rules for delta_record_aggregate and
delta_array_aggregate.

****************************************************************

From: Brad Moore
Sent: Saturday, June 11, 2016  9:20 PM

> Sure, but it *still* doesn't look like a loop.
[Editor's note: The above is from a thread filed in AI12-0189-1.]

The last thing I remember Jeff say before we headed back to our rooms after
dinner last night was something about having pleasant dreams about generators.
...  Thanks Jeff....

So here it is 3am, my thoughts returned to this email, and I am thinking this
is related to generators, which might be worth capturing if we are to discuss
tomorrow.

I think the Java idea could be adapted to syntax that looks more like a loop,
and it strikes me that the mechanism being used can be considered as a
generator approach.

Before I describe, first some examples of what it might look like.

The above example

   Total : Integer := 0;

    for I of Iterate(1, N).Parallel.Sum(Total) loop
       Total := Total + I;
   end loop;

Iterate(1,N) is a library call to a generator that creates a single "stream"
value that includes the start, end, and a result value (of type Integer) of
the iteration

Parallel is another library call that produces a generator and takes a
"stream" value and splits it into several substream values of "Chunks" of
iterations. The number of chunks is likely determined based on the number of
available cores. To get a sequential loop, from the above, you could just
delete the .Parallel.

Sum is an instantiation of a  "stream" collector library call that calls the
input generator produced by Parallel, to retrieve chunks, then produces in
parallel for each generator value, which is an integer. The parameter of Sum
(ie Total) is a external variable that is updated by the overall result. It
also happens to be the name of a in out parameter that is passed into a
callback that is represented by the loop body.

The loop body in fact is updating the local copy of the partial sum, and the
reduction occurs inside the Sum collector procedure, which updates the real
result.

The collector generic itself is can be a generic procedure that has two generic
formals, the identity value for the reduction, and the reducer function.

procedure Add is new Collector(Result_Type => Integer, Reduce => "+",
Identity => 0); Add could be a set of preinstantiated collectors that are
available for common use, but the programmer could create user-defined
collectors as well.

The callback probably takes also as parameters the start and end range of the
iteration, but the syntactic sugar of this loop syntax, hides that.

Now consider some other examples.

  -- Iterating through a map container by keys.
  for Pair of Container.Keys  loop
         Put_Line(Key_Type'Image(Pair.Key) & " => " &
           Elem_Type'Image(Pair.Elem));
   end loop;

Keys is a function that produces a generator for the name value pairs of the
container


  -- Iterating through a map container to produce parallel sum of elements.

  Total : Integer := 0;

  for Element of Container.Elements.Parallel.Sum(Total)  loop
         Total := Total + Element;
   end loop;

Elements is a function that produces a generator whose value is an element of
the container, rather than a name value pair.

-- Ada Environment variables.

    for Pair of Ada.Environment_Variables.Iterate loop
       Put_Line (Pair.Name & " => " & Pair.Value);
    end loop;

In this case, we'd probably need to define a Name_Value_Pair_Type and probably
a new Iterate subprogram that works with this type.


Anyway, please keep in mind it is 4am, I should probably know better to
compose emails at this time, as this might seem like a half-baked mess in the
morning. But it strikes me that this might be a nice mixture of ideas from
Tuck's loop body syntax, the generator proposal, and what Ive been thinking
of lately as an alternative.

The Java stream approach seems to be very flexible and powerful for
expression, but the Ada take on this would be better for Ada if it can make
it mechanism look more like a loop. 

****************************************************************

From: Florian Schnada
Sent: Thursday, September 29, 2016  9:16 AM

This is my attempt at implementing everything that was discussed and recorded
in the minutes (btw, thanks Randy for these, they are excellent!). I have also
attached a patch for the text file version. This may be more convenient for
you to apply. YMMV.

[Following was version /04 of the AI.]

****************************************************************

From: Edmond Schonberg
Sent: Thursday, September 29, 2016  4:29 PM

Excellent write-up!  One question about array delta aggregates: the text
suggests that each delta is a modification of a single component, but
discrete_choices include ranges and subtype indications, which imply slice
assignments. Are such choices excluded, or should the text mention indexed
components and slices as legal targets of a delta assignment?

****************************************************************

From: Randy Brukardt
Sent: Thursday, September 29, 2016  4:51 PM

I haven't read Florian's write up yet, but discrete range choices and the like
of aggregates are modeled as a loop in the language semantics -- the component
value is evaluated and assigned for each value of the range (in an unspecified
order).

I would have expected Florian's write-up to keep the semantics of each kind of
choice the same, so that there is as little new complication as possible.
(I'm sure he doesn't want to redescribe the various kinds of array choices and
their semantics.)

Ergo, there are no "slice assignments"; it's just a bunch of individual
components being updated. That's important for wording purposes (whether one
wants to think of it as a slice assignment is your own option, of course, but
the language certainly would not consider it so).

Specifically:
    (A delta 1..3 => Foo)
and (A delta 1 => Foo, 2 => Foo, 3 => Foo)

have exactly the same canonical semantics, and there is no slice anywhere to
be seen.

****************************************************************

From: Tucker Taft
Sent: Thursday, September 29, 2016  4:57 PM

> I haven't read Florian's write up yet, but discrete range choices and 
> the like of aggregates are modeled as a loop in the language semantics 
> -- the component value is evaluated and assigned for each value of the 
> range (in an unspecified order).
>
> I would have expected Florian's write-up to keep the semantics of each 
> kind of choice the same, so that there is as little new complication as possible.
> (I'm sure he doesn't want to redescribe the various kinds of array 
> choices and their semantics.)
>
> Ergo, there are no "slice assignments"; it's just a bunch of 
> individual components being updated. That's important for wording 
> purposes (whether one wants to think of it as a slice assignment is 
> your own option, of course, but the language certainly would not consider it so).

I agree with the above.

> Specifically:
>     (A delta 1..3 => Foo)
> and (A delta 1 => Foo, 2 => Foo, 3 => Foo)
>
> have exactly the same canonical semantics, and there is no slice 
> anywhere to be seen.

Agreed.  But I also haven't gone through the proposed wording in detail yet!

****************************************************************

From: Edmond Schonberg
Sent: Thursday, September 29, 2016  5:02 AM

> Specifically:
>    (A delta 1..3 => Foo)
> and (A delta 1 => Foo, 2 => Foo, 3 => Foo)
> 
> have exactly the same canonical semantics, and there is no slice 
> anywhere to be seen.
> 

Makes sense, and indeed the code will have to consist of individual
assignments.

****************************************************************

From: Tucker Taft
Sent: Thursday, September 29, 2016  5:13 PM

Generally, looks good!

But... I worry that we are referencing the semantics of 'Old and
build-in-place in the dynamic semantics section.  I could see mentioning
them in an AARM note.  But expecting the reader, as an aid to understanding
the dynamic semantics of delta aggregates, to have to look forward to the
definition of 'Old, followed by a perusal of the build-in-place rules, seems
downright perverse! ;-)  You have these references in brackets, so I presume
that means this is redundant information and hence not necessary to appear in
normative RM text here. If so, I heartily suggest that the bracketed wording
move to an AARM note.

****************************************************************

From: Randy Brukardt
Sent: Sunday, October 2, 2016  11:48 PM

> ... But expecting the
> reader, as an aid to understanding the dynamic semantics of delta 
> aggregates, to have to look forward to the definition of 'Old, 
> followed by a perusal of the build-in-place rules, seems downright 
> perverse! ;-)

I recognize the Hand of Baird in this text! ;-) Steve was originally a
co-author on this AI.

****************************************************************

From: Randy Brukardt
Sent: Sunday, October 2, 2016  11:24 PM

> This is my attempt at implementing everything that was discussed and 
> recorded in the minutes (btw, thanks Randy for these, they are 
> excellent!). I have also attached a patch for the text file version. 
> This may be more convenient for you to apply. YMMV.

One thing that was suggested in e-mail [by Bob, I think] (not the minutes)
was to completely separate the syntax and rules for record_delta_aggregate
and array_delta_aggregate, since they're mostly disjoint anyway. That should
decrease the verbiage. I was expecting this change to be made (because it was
obvious to me), but since it was left out of the minutes, I'm not surprised
it wasn't.

This could start something like:

4.3.4 Delta Aggregates

A (record or array) delta aggregate yields a composite value resulting from
copying another value of the same type and then subsequently assigning to some
(but typically not all) components of the copy.

Syntax

  record_delta_aggregate ::= (*base_*expression with delta
                              record_component_association_list)
 
  array_delta_aggregate ::= (*base_*expression with delta
                              array_component_association_list)

Name Resolution Rules

The expected type for a record_delta_aggregate shall be a single record type or
record extension. The expected type for an array_delta_aggregate shall be a
single array type. The expected type for the *base_*expression of either of
these agrgegates is the type of the enclosing record_delta_aggregate or
array_delta_aggregate

For a record_delta_aggregate, the expected type and applicable index constraint
of the expression in each record_component_association is defined as for a
record_component_association occurring within a record aggregate.

For an array_delta_aggregate, the expected type for each discrete_choice in an
array_component_association is the index type of type of the
array_delta_aggregate.

The expected type and applicable index constraint of the expression in
array_component_association is defined as for an array_component_association
occurring within an array aggregate of the type of the array_delta_aggregate.

....

You could even put them into separate clauses to get rid of all of the "for a
record delta aggregate ..."s.

****************************************************************

From: Randy Brukardt
Sent: Sunday, October 2, 2016  11:35 PM

Other comments on the draft:

For a delta aggregate the expression in a record_component_association or a
array_component_association shall not be of a limited type.

Which expression is being discussed here? I'd guess that it is supposed to be
the *base*_expression, and if that's the intent, this rule should say that. (Use
the prefix if you go through the trouble to define it!) [P.S. I took the extra
comma out of  your version.]

---

I second Tucker's comment about 'Old. I can't imagine what that has to do with 
aggregate semantics; it would make more sense if 'Old had been described in
terms of delta aggregate semantics.  I think that whatever semantics needs to
be described normatively, needs to be described here, and the rest can go into
an AARM note. We especially don't want a forward reference here.

---

In the examples, you need cross-references to where the objects/types are
declared elsewhere in the RM. For instance, the first example should have
something like "(See x.x.x for the declaration of D.)" as part of the comment.
I'm not going to try to figure out where an object named "D" is declared in
the RM! (Searching doesn't work for obvious reasons.)

****************************************************************

From: Randy Brukardt
Sent: Sunday, October 2, 2016  11:35 PM

Two other comments: 

> For a delta aggregate the expression in a record_component_association 
> or a array_component_association shall not be of a limited type.
> 
> Which expression is being discussed here? I'd guess that it is 
> supposed to be the *base*_expression, and if that's the intent, this 
> rule should say that. (Use the prefix if you go through the trouble to 
> define it!) [P.S. I took the extra comma out of  your version.]

The rule added after 7.5(2.10/2) has the same issue.

The reason this is important is by leaving out the prefix, the reader wonders
if that was on purpose.

---

You didn't update the rest of the AI, particularly the !discussion. I deleted
all of the multidimensional text, but otherwise left it unchanged.

PLEASE do not get in the habit of just updating the wording and leaving the
rest of it to the poor editor. The wording is often the easy part! And I am
not good at guessing what your intent is (which is what goes in the
discussion). I'll fix up headers and file e-mail, but that's it.

There's one other ARG member who is in that habit whom I won't name but will
identify as "Heave Beard", and it's important to point out that it isn't
acceptable. I don't have much hope of fixing Heave Beard but I don't plan to
let anyone else get away with it consistently.

****************************************************************

From: Florian Schanda
Sent: Tuesday, October 4, 2016  5:13 AM

> PLEASE do not get in the habit of just updating the wording and 
> leaving the rest of it to the poor editor. The wording is often the 
> easy part! And I am not good at guessing what your intent is (which is 
> what goes in the discussion). I'll fix up headers and file e-mail, but
> that's it.

Oh, right. I think I suffered from a mis-understanding then. I was imagining
I was told off before for changing the rest; so if its OK to change the bit 
before the wording then I shall do that!

I do want to be a good citizen :)

****************************************************************

From: Randy Brukardt
Sent: Wednesday, October 5, 2016  9:24 PM

> Oh, right. I think I suffered from a mis-understanding then. 
> I was imagining I was told off before for changing the rest; so if its 
> OK to change the bit before the wording then I shall do that!

Well, the !question (or !problem) should generally be left alone unless you
have explicit instructions to change them. It's the !summary, !proposal, and
!discussion (which FOLLOWS the wording) that should be updated if they
conflict in some way with the proposed wording.

> I do want to be a good citizen :)

Thanks. I realize your example for AIs was that Heave Beard guy, which is like
using Wally from Dibert's office as a model for hard work. :-) ("Heave Beard"
is good about one thing -- doing his homework early. I think he thinks that
gives me more time to finish it for him. ;-)

****************************************************************

From: Florian Schanda
Sent: Tuesday, October 4, 2016  9:14 AM

> But... I worry that we are referencing the semantics of 'Old and 
> build-in-place in the  dynamic semantics section.  I could see 
> mentioning them in an AARM note.  But expecting the reader, as an aid 
> to understanding the dynamic semantics of delta aggregates, to have to 
> look forward to the definition of 'Old, followed by a perusal of the 
> build-in-place rules, seems downright perverse! ;-)  You have these 
> references in brackets, so I presume that means this is redundant 
> information and hence not necessary to appear in normative RM text 
> here. If so, I heartily suggest that the bracketed wording move to an AARM
> note.

Yes, this is in square brackets (in the style of the SPARK RM). But really
for the Ada RM this should be an AARM clarification/note/something.

****************************************************************

From: Florian Schanda
Sent: Tuesday, October 4, 2016  9:20 AM

> For a delta aggregate the expression in a record_component_association 
> or a array_component_association shall not be of a limited type.
> 
> Which expression is being discussed here? I'd guess that it is 
> supposed to be the *base*_expression, and if that's the intent, this 
> rule should say that. (Use the prefix if you go through the trouble to 
> define it!) [P.S. I took the extra comma out of  your version.]

No, it really does mean the expression in each
record_component_association_list or array_component_association_list.
The base_expression can be of a limited type.

What we wanted to stop was having an assignment to a component that is
of limited type.

****************************************************************

From: Florian Schanda
Sent: Tuesday, October 4, 2016  9:21 AM

> In the examples, you need cross-references to where the objects/types 
> are declared elsewhere in the RM. For instance, the first example 
> should have something like "(See x.x.x for the declaration of D.)" as 
> part of the comment. I'm not going to try to figure out where an 
> object named "D" is declared in the RM! (Searching doesn't work for 
> obvious reasons.)

Ok, I've done this. I'll send an updated version tomorrow that will
include these references.

****************************************************************

From: Florian Schanda
Sent: Wednesday, October 5, 2016  6:10 AM

Homework (attempt 2) for AI12-0127-1 (delta aggregates) [This is version /05
of the AI - Editor.]

And again, with comments from the mailing list applied.

****************************************************************

From: Steve Baird
Sent: Wednesday, October 5, 2016  12:12 PM

A few minor points.

> A (record, array) delta aggregate yields a composite value resulting 
> from copying another value of the same type

This is informal introductory text, so I'd suggest replacing "copying"
with "starting with" because the type of the aggregate can be limited.
We don't want to suggest that we are copying limited values.

>
> The expected type for a record_delta_aggregate shall be a record type, 
> or record extension.
>
> The expected type for an array_delta_aggregate shall be a single array 
> type.

Why is the word "single" missing in the record case?
Note that the analogous rule in 4.3.1 says "shall be a single record type
or record extension".

> For an array_delta_aggregates, the expected type for each 
> discrete_choice in an array_component_association is the index type of 
> type of the delta aggregate.

Only a language lawyer would care about this one, but ...

A name resolution rule shouldn't depend on a legality rule.
So strictly speaking this should really say something like "the first index
type" even though
    a) later on a legality rule will impose a requirement that that
       the array type's dimensionality is 1; and
    b) the text is clearer to the casual reader as it stands and
       would probably require a clarifying note after this
       "correction".

****************************************************************

From: Randy Brukardt
Sent: Wednesday, October 5, 2016  7:41 PM

> > A (record, array) delta aggregate yields a composite value resulting 
> > from copying another value of the same type
> 
> This is informal introductory text, so I'd suggest replacing "copying" 
> with "starting with" because the type of the aggregate can be limited. 
> We don't want to suggest that we are copying limited values.

Right. I've made an updated version of the AI with the first two of Steve's
changes and a number of typo and formatting changes. So we can waste less
time at the meeting enumerating typos. ;-)

On this topic, it might make sense to have a note somewhere that the
*base*_expression would have to be a new limited value (following the rules
of 7.5); you can't use this construct to modify an existing limited object (as
an aggregate is a new object, so using an existing object would make a copy of
that object).

[I *did not* add such a note, but we should consider it.]

Also on this topic, 7.5 has an AARM Note:

AARM Ramification: Note this does not permit the *base_*expression of an
array_delta_aggregate to be of limited type as this is a useless construct
(you would not be able to update anything).

It took me a while to figure this out. I believe the point is that it isn't
possible to have declared limited array with non-limited components. [I suspect
that this idea is incorrect in bizarre corner cases, but it probably isn't
worth having support for this that only useful in pathological cases.]

However, if we're not going to allow limited *base*_expressions for an
array_delta_aggregate, then we need a Legality Rule to that effect in 4.3.4.
(And the AARM note needs to reflect that as well.) That fact would just be
buried in 7.5, a long way from 4.3.4.

[I made these changes in my update.]

> > The expected type for a record_delta_aggregate shall be a record 
> > type, or record extension.
> >
> > The expected type for an array_delta_aggregate shall be a single 
> > array type.
> 
> Why is the word "single" missing in the record case?
> Note that the analogous rule in 4.3.1 says "shall be a single record 
> type or record extension".

Looks like a mistake to me; there's also an extra comma. I made those changes
in my update.

> > For an array_delta_aggregates, the expected type for each 
> > discrete_choice in an array_component_association is the index type 
> > of type of the delta aggregate.
> 
> Only a language lawyer would care about this one, but ...
> 
> A name resolution rule shouldn't depend on a legality rule.
> So strictly speaking this should really say something like "the first 
> index type" even though
>     a) later on a legality rule will impose a requirement that that
>        the array type's dimensionality is 1; and
>     b) the text is clearer to the casual reader as it stands and
>        would probably require a clarifying note after this
>        "correction".

I think this is too pedantic. Who cares what index type gets used for an
illegal aggregate? We can discuss in PA.

---

I also changed most of the "array delta aggregate"s to the syntax form (with
underscores). The form without underscores informally usually is taken to mean
the same thing as the syntax form, but not always in the RM, and I'd rather
avoid new terms if possible. And "aggregate" is almost always in the syntax
form in the RM.

---

The first rule in the Dynamic Semantics

The evaluation of a delta_aggregate begins with evaluating the expression of
the delta aggregate and using that value to create and initialize the
aggregate's anonymous object.

is missing the *base*_ prefix for the expression. (We have it, why not use
it??) I fixed this, too.

---

Simple use in a postcondition:

  Post => D = (D'Old with delta Day => 12)
  --  see 3.8 for type Date

  Post => V = (V'Old with delta A .. B => 42.0, V'First => 0.0);
  --  see 3.6 for type Vector

We need the declarations of D, V, A, and B here. I suggest:

  procedure Twelfth (D : in out Date) -- see 3.8 for type Date
     with Post => D = (D'Old with delta Day => 12);

  procedure The_Answer (V : in out Vector; A, B : in Integer) -- see 3.6 for type Vector
     with Post => V = (V'Old with delta A .. B => 42.0, V'First => 0.0);

---

  N := (Min_Cell (L) with delta Value => 42);
  --  see 6.1 for declaration of Min_Cell

Same here with L and N. I suggest using Link and Cell from 3.10.1, so

  New_Cell : Cell := Min_Cell (Link) with delta Value => 42);
     -- see 3.10.1 for Cell and Link; 6.1 for Min_Cell

Next example needs a declaration of A1, which I suggest making there by adding ": Vector".

Finally:

  R := ((D with delta Day => 12) with delta Day => 42);
  --  see 3.8 for type Date

Needs declarations for R and D. I suggest using the objects already declared
in 3.8. Moreover, I think it would be best if this aggregate made sense (what
the heck is the 42th of a month??) and thus used a different component:

  Tomorrow := ((Yesterday with delta Day => 12) with delta Month => Apr); -- see 3.8

---

Thanks again for the update; I should have messed it up enough. ;-) [I'll post
the update once I've gotten caught up processing homework.]

****************************************************************

From: Stephen Leake
Sent: Saturday, August 5, 2017  12:15 PM

!topic typos in ai12-0127
!reference Ada 202x RM4.3.4
!from Stephen Leake 2017-08-05
!keywords delta aggregates
!discussion

I just read ai12-0127 (at
http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0127-1.txt?rev=1.10)
(with an eye towards enhancing Emacs Ada mode to support the new syntax), and
I noticed a few typos:


4.3.4
    For an array_delta_aggregates, the expected type for each
    discrete_choice in an array_component_association is the index type of
    type of the delta aggregate.

       "array_delta_aggregates" should not be plural

Examples:

    New_Cell : Cell := Min_Cell (Link) with delta Value => 42);

        missing left paren before Min_Cell

    A1 : Vector := ((1, 2, 3) with delta Integer (Random * 3.0) => 14.2);

        components in base expression must be real; (1.0, 2.0, 3.0)

****************************************************************

From: Christoph Grein
Sent: Wednesday, August 9, 2017  9:30 AM

The record Rec of this example seems to have among others the two components
Color and Shape. Thus the Post condition seems to return False:

    procedure Foo (Fighters : in out Rec)
       with Post => (Fighters.Colour = Black and
                     Fighters = (Fighters'Old with delta Shape => Trapazoid));

Shouldn't this be

    procedure Foo (Fighters : in out Rec)
       with Post => (Fighters = (Fighters'Old with delta
                                   Shape  => Trapazoid,
                                   Colour => Black));

(This example is not part of the examples of the wording section, so the error
is not overly fatal, because it won't go into the RM.)

****************************************************************

From: Simon Wright
Sent: Wednesday, August 9, 2017  10:26 AM

> The record Rec of this example seems to have among others the two 
> components Color and Shape. Thus the Post condition seems to return False:
> 
>   procedure Foo (Fighters : in out Rec)
>      with Post => (Fighters.Colour = Black and
>                    Fighters = (Fighters'Old with delta Shape => 
> Trapazoid));

Spello: TrapEzoid

****************************************************************

From: Gary Dismukes
Sent: Wednesday, August 9, 2017  11:56 AM

> Shouldn't this be
> 
>    procedure Foo (Fighters : in out Rec)
>       with Post => (Fighters = (Fighters'Old with delta
>                                   Shape  => Trapazoid,
>                                   Colour => Black));
> 
> (This example is not part of the examples of the wording section, so 
> the error is not overly fatal, because it won't go into the RM.)

Sounds right to me.

Maybe the spelling should also be fixed: "Trapazoid" should be "Trapezoid". :-)

****************************************************************

From: Randy Brukardt
Sent: Wednesday, August 9, 2017  10:39 PM

> I just read ai12-0127 (at
> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0127-1.t
> xt?rev=1.10)
> (with an eye towards enhancing Emacs Ada mode to support the new 
> syntax), and I noticed a few typos:
...

Thanks, I think. Since this is an open AI, it hasn't yet undergone a
comprehensive editorial review, and it is not unusual for it to contain a
bunch of typos. In this particular case, the AI is awaiting an update and a
number of problems (including typos) are supposed to be fixed by the author.
At least part of the text is likely to change substantially.

In any case, the editor (that would be me) is not in a position to make
changes to this AI or most other AIs (other than the ones assigned to me)
as there is a race condition between me and the actual author. Experience
shows that attempts to fix things often disappear in the next draft anyway
(when the author starts from some other version of the AI). I'll file this
mail into the AI, where it might very well be forgotten (or even disappear as
a victim of a race condition).

As such, it's not very valuable to make editorial comments on open AIs outside
of ARG meetings (or even in ARG meetings, as a significant number of AIs are
redrafted without fixing them). They're best left until the AI becomes
ARG-approved and is in its editorial review period. Either that or contact the
AI author (you can find who that is in the most recent version of the ARG
meeting minutes - if it's not assigned to anyone, it's in near-death limbo and
not worth worrying about).

****************************************************************

From: Steve Baird
Sent: Thursday, October 5, 2017  7:12 PM

I was tasked with making a nit-picking pass over this AI.

All I found was the following, presented in the usual grocery-list normal form.

====



"starting with another value" => "starting with a copy of another value"

---

"is the index type of type of the delta aggregate" => "is the index type of
THE type of the delta aggregate"

---

In 4.3.3(17/5) replace
   ... only if it is the single discrete_choice of its
   discrete_choice_list, and there is only one
   array_component_association in the array_aggregate.
with
   ..  only if it is the single discrete_choice of its
       discrete_choice_list, and either there is only one
       array_component_association in the
       enclosing array_component_association_list or the enclosing
       aggregate is an array_delta_aggregate
       REDUNDANT:[, not an array_aggregate].

We want to allow

   (X with delta Lo1 .. Hi1 => This, Lo2 .. Hi2 => That)

where every expression in sight is non-static, but we don't want to allow

   (X with delta Lo1 .. Hi1 | Lo2 .. Hi2 => This)

in that case.

---

In the legality rules, we've got
   "the record_component_association shall not use the box
    symbol <>"

The use of the word "the" incorrectly presupposes that there is exactly one
record_component_association. Ditto for "and the component_choice_list shall
not use others".

****************************************************************

From: Randy Brukardt
Sent: Thursday, October 5, 2017  7:47 PM

> I was tasked with making a nit-picking pass over this AI.

You're tasked with producing a full update based on the discussion from last
October (it wasn't updated for Vienna so it wasn't discussed). It was assigned
to you as "this sort of detail seems like a job for Steve Baird"
(quoting from the Pittsburgh minutes).

(The "sort of detail" is checking that the wording is consistent with all of
the existing aggregate wording; I was personally concerned with record
component completeness rules, but others are called out in the minutes --
enough issues had been brought up that a complete check seemed to be needed.)

This is an important AI that it would be good to progress.

> All I found was the following, presented in the usual grocery-list 
> normal form.

I could deal with the first three, but the fourth is just a complaint without
a fix. As the (now) primary author, you need to propose a fix for everything.

****************************************************************

From: Gary Dismukes
Sent: Thursday, October 5, 2017  7:54 PM

I happened to notice that the last update to this AI (sent by Florian) happened
exactly a year ago, although the current date on the AI is shown as Oct. 6,
2016.

****************************************************************

From: Gary Dismukes
Sent: Thursday, October 5, 2017  7:58 PM

Sorry for the noise!  My frivolous message was only intended to be sent to Mr.
Baird.  (And sorry also for this additional noise...)

****************************************************************

From: Randy Brukardt
Sent: Thursday, October 5, 2017  8:16 PM

..
> I happened to notice that the last update to this AI (sent by
> Florian) happened exactly a year ago, although the current date on the 
> AI is shown as Oct. 6, 2016.

I did notice that the AI was almost exactly a year old when replying to Steve,
but I didn't see any need to work that in to my reply. The Ghost AI will be
dated today, for instance, since I'm processing it tonight.

I usually date AIs the date that I post them, which is not necessarily the
date that they got sent to me. (Sometimes I adjust the date to ensure that
every version has a different date, and sometimes I just do something else
for no reason.)

So now more noise has been generated. ;-)

Moral: Take care when replying the mail from the ARG list, as the list is set
up to encourage public replies to the list and not the private replies to the
author.

****************************************************************

From: Steve Baird
Sent: Thursday, October 5, 2017  7:12 PM

****************************************************************

Questions? Ask the ACAA Technical Agent