Annotated Ada Reference Manual (Ada 202y Draft 1)Legal Information
Contents   Index   References   Search   Previous   Next 

4.3.4 Delta Aggregates

1/5
{AI12-0127-1} {AI12-0324-1} Evaluating a (record or array) delta aggregate yields a composite value that starts with a copy of another value of the same type and then assigns to some (but typically not all) components of the copy.

Syntax

2/5
{AI12-0127-1} delta_aggregate ::= record_delta_aggregate | array_delta_aggregate
3/5
{AI12-0127-1} record_delta_aggregate ::= 
    (base_expression with delta record_component_association_list)
4/5
{AI12-0127-1} {AI12-0212-1} array_delta_aggregate ::= 
    (base_expression with delta array_component_association_list)
  | '[' base_expression with delta array_component_association_list ']'

Name Resolution Rules

5/5
{AI12-0127-1} The expected type for a record_delta_aggregate shall be a single descendant of a record type or record extension.
6/5
{AI12-0127-1} The expected type for an array_delta_aggregate shall be a single array type.
7/5
{AI12-0127-1} The expected type for the base_expression of any delta_aggregate is the type of the enclosing delta_aggregate.
8/5
{AI12-0127-1} [The Name Resolution Rules and Legality Rules for each record_component_association of a record_delta_aggregate are as defined in 4.3.1.]
9/5
{AI12-0127-1} For an array_delta_aggregate, the expected type for each discrete_choice in an array_component_association is the index type of the type of the delta_aggregate.
10/5
{AI12-0127-1} The expected type of the expression in an 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

11/5
{AI12-0127-1} For an array_delta_aggregate, the array_component_association shall not use the box symbol <>, and the discrete_choice shall not be others.
12/5
{AI12-0127-1} For an array_delta_aggregate, the dimensionality of the type of the delta_aggregate shall be 1.
13/5
{AI12-0127-1} For an array_delta_aggregate, the base_expression and each expression in every array_component_association shall be of a nonlimited type.
13.a/5
Ramification: The base_expression of a record_delta_aggregate may be of a limited type (for example a record with limited components), as it is not restricted. A rule in 4.3.1 ensures that we do not assign to a limited component. We do not allow any part of an array_delta_aggregate to be of a limited type, even the base_expression, as this is a useless construct (you would not be able to update anything because the components necessarily are also limited except in pathological cases). 

Dynamic Semantics

14/5
{AI12-0127-1} {AI12-0324-1} {AI12-0381-1} The evaluation of a delta_aggregate begins with the evaluation of the base_expression of the delta_aggregate; then that value is used to create and initialize the anonymous object of the aggregate. The bounds of the anonymous object of an array_delta_aggregate and the discriminants (if any) of the anonymous object of a record_delta_aggregate are those of the base_expression. If a record_delta_aggregate is of a specific tagged type, its tag is that of the specific type; if it is of a class-wide type, its tag is that of the base_expression.
14.a/5
Ramification: This is the same anonymous object as described in 7.6, “Assignment and Finalization”; in particular, it might be required to be built in place.
14.b/5
For a specific tagged type, any extension components that the actual object underlying the base_expression might have are not used to initialize the anonymous object, which is critical if the aggregate is required to be built-in-place. 
14.c/5
To be honest: The anonymous object associated with the evaluation of a delta_aggregate begins its life as a variable, not a constant (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. 
15/5
{AI12-0127-1} For a record_delta_aggregate, for each component associated with each record_component_association (in an unspecified order): 
16/5
if the associated component belongs to a variant, a check is made that the values of the discriminants are such that the anonymous object has this component. The exception Constraint_Error is raised if this check fails.
17/5
the expression of the record_component_association is evaluated, converted to the nominal subtype of the associated component, and assigned to the component of the anonymous object.
18/5
{AI12-0127-1} For an array_delta_aggregate, for each discrete_choice of each array_component_association (in the order given in the enclosing discrete_choice_list and array_component_association_list, respectively) the discrete_choice is evaluated; for each represented index value (in ascending order, if the discrete_choice represents a range): 
19/5
the index value is converted to the index type of the array type.
20/5
a check is made that the index value belongs to the index range of the anonymous object of the aggregate; Constraint_Error is raised if this check fails.
21/5
the component expression is evaluated, converted to the array component subtype, and assigned to the component of the anonymous object identified by the index value.
21.a/5
Reason: Unlike other aggregates, an array_delta_aggregate is evaluated in the order that it is written. This is necessary to get deterministic behavior, as (unlike other aggregates, including record_delta_aggregates) there is no requirement that the specified components be distinct. As such, the order requirement ensures that every array_delta_aggregate has a well-defined result, even if the same component is specified multiple times. 

Examples

22/5
{AI12-0127-1} {AI12-0429-1} Examples of use of delta aggregates in a postcondition:
23/5
procedure Twelfth (D : in out Date) -- see 3.8 for type Date
   with Post => D = (D'Old with delta Day => 12);
24/5
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);
25/5
{AI12-0127-1} {AI12-0324-1} {AI12-0379-1} {AI12-0386-1} {AI12-0429-1} Examples where the base expression is nontrivial:
26/5
New_Cell : Cell := (Min_Cell (Head) with delta Value => 42);
   -- see 3.10.1 for Cell and Head; 6.1 for Min_Cell
27/5
A1 : Vector := ((0 => 1.0, 1 => 2.0, 2 => 3.0)
       with delta Integer(Random * 2.0) => 14.2);
   -- see 3.6 for declaration of type Vector
   -- see 6.1 for declaration of Random
28/5
Tomorrow := ((Yesterday with delta Day => 12)
                  with delta Month => April); -- see 3.8
29/5
{AI12-0127-1} {AI12-0379-1} {AI12-0429-1} Example where the base expression is class-wide:
30/5
function Translate (P : Point'Class; X, Y : Real) return Point'Class is
   (P with delta X => P.X + X,
                 Y => P.Y + Y); -- see 3.9 for declaration of type Point

Extensions to Ada 2012

30.a/5
{AI12-0127-1} Delta aggregates are new. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe