Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
Annotated Ada Reference Manual (Ada 2022)Legal Information
Contents   Index   References   Search   Previous   Next 

4.3.4 Delta Aggregates

{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. 


{AI12-0127-1} delta_aggregate ::= record_delta_aggregate | array_delta_aggregate
{AI12-0127-1} record_delta_aggregate ::= 
    (base_expression with delta record_component_association_list)
{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

{AI12-0127-1} The expected type for a record_delta_aggregate shall be a single descendant of a record type or record extension.
{AI12-0127-1} The expected type for an array_delta_aggregate shall be a single array type.
{AI12-0127-1} The expected type for the base_expression of any delta_aggregate is the type of the enclosing delta_aggregate.
{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.]
{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.
{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

{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.
{AI12-0127-1} For an array_delta_aggregate, the dimensionality of the type of the delta_aggregate shall be 1.
{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.
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

{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.
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.
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. 
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. 
{AI12-0127-1} For a record_delta_aggregate, for each component associated with each record_component_association (in an unspecified order): 
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.
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.
{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): 
the index value is converted to the index type of the array type.
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.
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.
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. 


{AI12-0127-1} {AI12-0429-1} Examples of use of delta aggregates 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);
{AI12-0127-1} {AI12-0324-1} {AI12-0379-1} {AI12-0386-1} {AI12-0429-1} Examples where the base expression is nontrivial:
New_Cell : Cell := (Min_Cell (Head) with delta Value => 42);
   -- see 3.10.1 for Cell and Head; 6.1 for Min_Cell
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
Tomorrow := ((Yesterday with delta Day => 12)
                  with delta Month => April); -- see 3.8
{AI12-0127-1} {AI12-0379-1} {AI12-0429-1} Example where the base expression is class-wide:
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

{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