Version 1.5 of 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]); --
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); --
procedure P (A : Int_Array); --
P ((1, 2)); --
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