Version 1.5 of ai12s/ai12-0307-1.txt

Unformatted version of ai12s/ai12-0307-1.txt version 1.5
Other versions for file ai12s/ai12-0307-1.txt

!standard 4.3(3/5)          19-03-04 AI12-0307-1/03
!reference AI12-0212-1
!class Amendment 19-02-04
!status Amendment 1-2012 19-02-11
!status WG9 Approved 22-06-22
!status ARG Approved 8-0-2 19-02-11
!status work item 19-02-04
!status received 19-01-22
!priority Low
!difficulty Easy
!subject Resolution of aggregates
!summary
Resolution of all aggregates work the same; anything that could be a legal aggregate is allowed for resolution purposes.
!problem
4.3(3/2) was revised by AI12-0212-1 to read:
The expected type for a delta_aggregate shall be a single array type, or a single descendant of a record type or of a record extension. The expected type for an array_aggregate, a record_aggregate, or an extension_aggregate shall be a single array type, record type, or record extension. The expected type for a container_aggregate shall be a single array type or a single type with the Aggregate aspect specified.
The syntax of array_aggregate was also extended to allow square brackets.
However, this leaves the resolution of an aggregate like:
[1, 2]
ambiguous. It could be either a container_aggregate or an array_aggregate, and the type it resolves to determines which.
However, if resolved as an array_aggregate, a record type is considered, and if resolved as a container_aggregate, a record type is not considered. So there exist cases where whether or not resolution will succeed is unknown:
procedure P (V : Vector); procedure P (R : My_Rec);
P ([1, 2]); -- OK? Ambiguous? (Illegal.)
This needs to be fixed.
!proposal
(See Summary.)
!wording
Replace 4.3(3/5) with:
The expected type for an aggregate shall be a single array type, a single type with the Aggregate aspect specified, or a single descendant of a record type or of a record extension.
!discussion
There are four reasonable solutions, ranked in ascending order of incompatibility:
(1) parens or brackets changes the resolution:
The expected type for a delta_aggregate shall be a single array type, or a single descendant of a record type or of a record extension. The expected type for an array_aggregate surrounded with parentheses, a record_aggregate, or an extension_aggregate shall be a single array type, record type, or record extension. The expected type for a container_aggregate or an array_aggregate surrounded with brackets shall be a single array type or a single type with the Aggregate aspect specified.
(2) Only delta aggregates are treated specially:
The expected type for a delta_aggregate shall be a single array type, or a single descendant of a record type or of a record extension. The expected type for any other aggregate shall be a single array type, single record type, single record extension, or a single type with the Aggregate aspect specified.
(3) All aggregates are resolved the same:
The expected type for an aggregate shall be a single array type, a single type with the Aggregate aspect specified, or a single descendant of a record type or of a record extension.
(4) We use the least information possible.
The expected type for an aggregate shall be a single composite type.
(1) is unusual in that the syntax of the aggregate determines the resolution. And the syntax difference in question is subtle (especially in some fonts). We would prefer that all array aggregates resolve the same way.
However, all of the remaining options are incompatible. For such an incompatibility to happen, we need a subprogram that takes a parameter that is an aggregate, and we need an overloaded version of that subprogram that has a parameter of a second type that doesn't currently have aggregates but will in Ada 2020. In that case, a call that resolves in Ada 2012 will become ambiguous in Ada 2020.
For instance, all of (2) through (4) are incompatible in a case like:
procedure P (V : Vector); -- From an instance of Ada.Containers.Vectors. procedure P (A : Int_Array); -- Some array with integer components.
P ((1, 2)); -- OK in Ada 2012, Ambiguous in Ada 2020.
Clearly, overloading like this is not very common. So the incompatibility is probably tolerable.
All of the proposed wordings (except (1), of course) have this problem if the second type is a container type (almost any container type, except holders, queues, and trees). Some users use containers extensively.
On the other hand, the second type for (3) and (4) can also be a private type that has visible non-discriminant components. While such types can exist, they are rare in practice. Typically, a type is private until such a point where the components become visible (meaning that the last declaration is a record extension, which has allowed aggregates since Ada 95, and thus isn't involved in the incompatibility.)
Thus, if we're going to allow any incompatibility, we might as well allow the delta aggregate incompatibility as well, as it is far less likely than the container incompatibility. Therefore, we select option (3).
We don't select option (4), as it means that the second type could be any private type. Private types are quite common in Ada, and since we don't actually allow any aggregates to be fully private types, we aren't gaining anything from this addition risk of incompatibility. If we were designing Ada from scratch, this is the option we would choose, since we don't want resolution to be "too smart". But it seems too late to be introducing unnecessary incompatibilities.
!corrigendum 4.3(3/2)
Replace the paragraph:
The expected type for an aggregate shall be a single array type, record type, or record extension.
by:
The expected type for an aggregate shall be a single array type, a single type with the Aggregate aspect specified, or a single descendant of a record type or of a record extension.
!ASIS
No effect.
!ACATS test
ACATS B-Tests are be needed to check that newly incompatible cases are properly detected.
!appendix

From: Randy Brukardt
Sent: Tuesday, January 22, 2019  5:54 PM

4.3(3/2) was revised by AI12-0212-1 to read:

  The expected type for a delta_aggregate shall be a single array type,
  or a single descendant of a record type or of a record extension. The
  expected type for [any other aggregate] {an array_aggregate, a
  record_aggregate, or an extension_aggregate} shall be a single array
  type, record type, or record extension. {The expected type for a
  container_aggregate shall be a single array type or a single type with
  the Aggregate aspect specified.}

The syntax of array_aggregate was also extended to allow square brackets.

So how does an aggregate like:
    [1, 2]
get resolved? It could be either a container_aggregate or an array_aggregate, 
and the type it resolves to determines that. (Remember, aggregates have a 
weird resolution, where the rule I give above determines how they are 
resolved from the outside, and then there are more specific rules that
determine what kind of aggregate one has and how the inside is resolved.)

Consider:
    procedure P (V : Vector);
    procedure P (R : My_Rec);

    P ([1, 2]); -- OK? Ambiguous?

In this case, we have a routine overloaded on a container and a vector. If 
we assume the aggregate is a container_aggregate, this resolves (the record
type isn't considered). If we assume the aggregate is an array_aggregate 
(which it could be syntactically), this does not resolve (the record type
is considered).

I wonder if the author (Tuck??) was thinking of having separate rules for 
aggregates surrounded by square brackets rather than round brackets. If 
that's the case, though, we can't use the syntactic category for 
array_aggregate alone, and rather need to say something about the
brackets/parens:

  The expected type for a delta_aggregate shall be a single array type,
  or a single descendant of a record type or of a record extension. The
  expected type for [any other aggregate] {an array_aggregate surrounded with
  parentheses, a record_aggregate, or an extension_aggregate} shall be a 
  single array type, record type, or record extension. {The expected type for 
  a container_aggregate or an array_aggregate surrounded with brackets shall 
  be a single array type or a single type with the Aggregate aspect specified.}

However, Bob likes to say that resolution shouldn't be too smart. And the 
presence or absence of brackets seems a bit dodgy to use for resolution.
Using the above wording, consider:

    procedure P (A : My_Array);
    procedure P (R : My_Rec);

    P ([1, 2]); -- OK.
    P ((1, 2)); -- Ambiguous.

So perhaps it would be better to forget having separate rules and just mash 
them all up (returning to wording much more similar to the original):

  The expected type for a delta_aggregate shall be a single array type,
  or a single descendant of a record type or of a record extension. The
  expected type for any other aggregate shall be a single array
  type, record type, [or] record extension{, or a single type with the
  Aggregate aspect specified}. 

This does have a bit of a compatibility problem, as the most of the existing 
Ada.Containers will have the Aggregate aspect. So with the above rule:

    package My_Vectors is new Ada.Containers.Vectors (....);
    procedure P (V : My_Vectors.Vector);
    procedure P (R : My_Rec);

    P ((1, 2)); -- OK in Ada 2012, Ambiguous in Ada 2020.

We cared enough about compatibility to separate out delta aggregates just so 
that private parents would be allowed for them and not for other aggregates.
That's a lot less likely than the above. So I guess the shorter rule given 
above doesn't work, either.

So it looks to me like we need to use the rule with the brackets/parens 
mentioned.

Any other ideas? If not, I'll write up a clean-up AI for this wording.

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

From: Edmond Schonberg
Sent: Tuesday, January 22, 2019  6:55 PM

...
> However, Bob likes to say that resolution shouldn't be too smart.

Fully agree, the resolution of aggregates is complex enough, and users 
have known for two decades that when in doubt you qualify.

...
> This does have a bit of a compatibility problem, as the most of the 
> existing Ada.Containers will have the Aggregate aspect. So with the above rule:
> 
>    package My_Vectors is new Ada.Containers.Vectors (....);
>    procedure P (V : My_Vectors.Vector);
>    procedure P (R : My_Rec);
> 
>    P ((1, 2)); -- OK in Ada 2012, Ambiguous in Ada 2020.

But the same will be true with two overloaded procedures that take different 
containers with Add_Unnamed, so qualification will be necessary. I don’t think
that the above is reason enough to complicate the rules. In particular  
[…] and (…) should be treated in the same way.

> 
> We cared enough about compatibility to separate out delta aggregates 
> just so that private parents would be allowed for them and not for other 
> aggregates. That's a lot less likely than the above. So I guess the 
> shorter rule given above doesn't work, either.
> 
> So it looks to me like we need to use the rule with the 
> brackets/parens mentioned.

Unnecessary complication, small incompatibility is much more acceptable IMHO.

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

From: Randy Brukardt
Sent: Tuesday, January 22, 2019  7:32 PM

> Unnecessary complication, small incompatibility is much more 
> acceptable IMHO.

If we're OK with this incompatibility, we should revisit the decision for 
delta aggregates (where the incompatibility is even less likely). That would 
let us have a much simpler overall rule:

  The expected type for an aggregate shall be a single array type,
  a single type with the Aggregate aspect specified, or a single
  descendant of a record type or of a record extension.

which is the union of all of the possibilities. Containers and types with some 
private components (private types or private extensions) would be newly 
allowed (and could cause incompatibilities -- but only if there is some 
overloading).

I note that the delta aggregate rule came from not wanting to introduce any 
incompatibility. The minutes of meeting 58 is the only place this came up, and
there wasn't any discussion of whether we could just allow the incompatibility
(at least not any that was recorded).

P.S. We've still got the Winter Storm Warning, but the expected snow hasn't 
really appeared yet (there's a dusting of snow, but hardly the 6-8 inches 
forecast). Thus I'm in the office. Of course, the snow could appear at any 
time. Will work until the end of the usual working day or it really starts to 
snow.

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

From: Edmond Schonberg
Sent: Tuesday, January 22, 2019  8:07 PM

> If we're OK with this incompatibility, we should revisit the decision 
> for delta aggregates (where the incompatibility is even less likely). 
> That would let us have a much simpler overall rule:
> 
>  The expected type for an aggregate shall be a single array type,  a 
> single type with the Aggregate aspect specified, or a single  
> descendant of a record type or of a record extension.
> 
> which is the union of all of the possibilities. Containers and types 
> with some private components (private types or private extensions) 
> would be newly allowed (and could cause incompatibilities -- but only 
> if there is some overloading).

No objections to this, although it is easy to justify a different rule for
delta aggregates because they have a visibly different syntax: we know what
it is without having to look at choices and expressions.

Speaking of which,   Can the presence of key-value pairs be used
for resolution  ( suppose not) ?

> I note that the delta aggregate rule came from not wanting to 
> introduce any incompatibility. The minutes of meeting 58 is the only 
> place this came up, and there wasn't any discussion of whether we 
> could just allow the incompatibility (at least not any that was recorded).
> 
> P.S. We've still got the Winter Storm Warning, but the expected snow 
> hasn't really appeared yet (there's a dusting of snow, but hardly the 
> 6-8 inches forecast). Thus I'm in the office. Of course, the snow 
> could appear at any time. Will work until the end of the usual working 
> day or it really starts to snow.

Keep warm!

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

From: Randy Brukardt
Sent: Tuesday, January 22, 2019  8:28 PM

> No objections to this, although it is easy to justify a different rule 
> for delta aggregates because they have a visibly different syntax: we 
> know what it is without having to look at choices and expressions.

You can make the exact same argument for [] vs. ().  Make up your mind! :-)

> Speaking of which,   Can the presence of key-value pairs be used
> for resolution  ( suppose not) ?

Nope. Not in Ada before 2020 nor in Ada 2020.

...
> > P.S. We've still got the Winter Storm Warning, but the expected snow 
> > hasn't really appeared yet (there's a dusting of snow, but hardly 
> > the
> > 6-8 inches forecast). Thus I'm in the office. Of course, the snow 
> > could appear at any time. Will work until the end of the usual 
> > working day or it really starts to snow.
> 
> Keep warm!

*That's* going to be challenging. The Friday and Saturday forecasts have a 
high of 0 (Fahrenheit), with lows of -13 and -17. I'd rather have the snow;
modern cars get better gas mileage in part because they make less waste heat
== takes longer to warm up the engine/cabin. In those sorts of temperatures,
I'll get home before the engine gets warm. And then it takes a long time to 
recover.

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

From: Tucker Taft
Sent: Tuesday, January 22, 2019  9:22 PM

>> No objections to this, although it is easy to justify a different 
>> rule for delta aggregates because they have a visibly different 
>> syntax: we know what it is without having to look at choices and 
>> expressions.
> 
> You can make the exact same argument for [] vs. ().  Make up your 
> mind! :-)

The [] vs. () is pretty subtle, and I would not recommending it being used 
for resolution (at least not yet -- maybe some day).  I see no reason to 
backtrack on delta aggregates.  So I would accept the modest incompatibility 
with container aggregates, and leave delta aggregates as somewhat more complex
to avoid incompatibility.  But I could also accept the mild incompatibility 
with delta aggregates to simplify the rules.  I don't think anyone is going to 
bump into this problem.

So anyone else feel strongly about delta aggregates either way?  I'm willing 
to let our editor make the decision, perhaps based on how many inches of snow
fall in Wisconsin ... ;-)

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

From: John Barnes
Sent: Wednesday, January 23, 2019  1:55 AM

It's cold here in England as well. We had about two millimetres of snow 
yesterday. And the temperature has plunged to minus 2 Celsius.

Let the editor decide on the parens.

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

From: Edmond Schonberg
Sent: Wednesday, January 23, 2019  8:46 AM

>> No objections to this, although it is easy to justify a different 
>> rule for delta aggregates because they have a visibly different 
>> syntax: we know what it is without having to look at choices and 
>> expressions.
> 
> You can make the exact same argument for [] vs. ().  Make up your 
> mind! :-)

Not my mind, my eyes: if the screen is not bright enough I’ll have troubles 
between [()], (()). [[]]. etc (the ADA should have something to say about 
that!).  A “with” jumps out, but I’ll go for the simplest: all aggregates are
objects of some composite type whose expected type is determined from context.

>> Speaking of which,   Can the presence of key-value pairs be used
>> for resolution  ( suppose not) ?
> 
> Nope. Not in Ada before 2020 nor in Ada 2020.

Great!

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

Questions? Ask the ACAA Technical Agent