Version 1.3 of ai12s/ai12-0306-1.txt

Unformatted version of ai12s/ai12-0306-1.txt version 1.3
Other versions for file ai12s/ai12-0306-1.txt

!standard 4.3.3(2)          19-02-12 AI12-0306-1/02
!standard 4.3.3(3/5)
!standard 4.3.3(9/5)
!standard 4.3.3(26/5)
!standard 4.3.3(26.1/5)
!standard 4.3.3(33/3)
!standard 4.3.3(38)
!standard 4.3.3(39)
!standard 4.3.3(42)
!reference AI12-0212-1
!class Amendment 19-02-04
!status Amendment 1-2012 19-02-12
!status ARG Approved 9-1-0 19-02-12
!status work item 19-02-04
!status received 19-01-23
!priority Low
!difficulty Easy
!subject Split null array aggregates from positional array aggregates
!summary
Change the syntax slightly to improve the wording of array aggregates.
!problem
The wording for null array aggregates seems unnecessarily complicated, defining a term and having to exclude that term from the bounds bullet.
Also, some of the array aggregate examples ought to show the use of square brackets. And the first Note is now nonsense.
!proposal
(See Summary.)
!wording
Starting from the wording of AI12-0212-1:
Replace 4.3.3(2) with:
array_aggregate ::= positional_array_aggregate | null_array_aggregate | named_array_aggregate
Replace 4.3.3(3/2) with:
positional_array_aggregate ::= (expression, expression {, expression}) | (expression {, expression}, others => expression) | (expression {, expression}, others => <>) | '[' expression{, expression}[, others => expression] ']' | '[' expression{, expression}, others => <> ']'
null_array_aggregate ::= '[' ']'
Modify 4.3.3(9/5):
An array_aggregate of an n-dimensional array type shall be written as an n-dimensional array_aggregate, or as a {null_array_aggregate}[/null aggregate/ -- [ ]].
Add after 4.3.3(20):
AARM To Be Honest: This is true even in cases where there is no corresponding legal positional_array_aggregate.
[Author's note: We could have fixed this wording to make an equivalence of a null string_literal with a null_array_aggregate. However, considering that for Ada prior to Ada 2020, neither null or single character positional_array_aggregates existed, and we've never considered that a problem, why go all pedantic now?]
Revert 4.3.3(26) to its Ada 95 version. (This removes "that is not a null aggregate".)
Modify 4.3.3(26.1/5):
For a {null_array_aggregate}[null aggregate], bounds for each dimension are determined as for a positional_array_aggregate with zero expressions for each dimension;}
AARM Reason: We need a separate rule to describe what happens for a multidimensional null_array_aggregate; we could've combined the single dimension case with the positional_array_aggregate rule.
Replace 4.3.3(33/3) with:
In an array_aggregate {delimited by parentheses}, positional notation may only be used with two or more expressions; a single expression in parentheses is interpreted as a parenthesized expression. {An array_aggregate delimited by brackets}[A named_array_aggregate, such as (1 => X),] may be used to specify an array with a single component.
[Author's note: Just noticed that this Note is now a lie.]
Change a few existing examples to use square brackets:
Replace 4.3.3(38) with:
(1 .. 5 => (1 .. 8 => 0.0)) -- two-dimensional [1 .. N => new Cell] -- N new cells, in particular for N = 0
Replace 4.3.3(39) with:
Table'(2 | 4 | 10 => 1, others => 0) Schedule'(Mon .. Fri => True, others => False) -- see 3.6 Schedule'[Wed | Sun => False, others => True] Vector'(1 => 2.5) -- single-component vector
Replace 4.3.3(42) with:
((1.1, 1.2, 1.3), (2.1, 2.2, 2.3)) (1 => [1.1, 1.2, 1.3], 2 => [2.1, 2.2, 2.3]) [1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3)]
!discussion
This presentation is more like the presentation of container aggregates, and it simplifies some of the wording.
!corrigendum 4.3.3(2)
Replace the paragraph:
array_aggregate ::= 
    positional_array_aggregate | named_array_aggregate
by:
array_aggregate ::= 
    positional_array_aggregate | null_array_aggregate | named_array_aggregate
!corrigendum 4.3.3(3/2)
Replace the paragraph:
positional_array_aggregate ::= 
    (expressionexpression {, expression})
  | (expression {, expression}, others => expression)
  | (expression {, expression}, others => <>
by:
positional_array_aggregate ::= 
    (expressionexpression {, expression})
  | (expression {, expression}, others => expression)
  | (expression {, expression}, others => <>)
  | '[' expression {, expression}[, others => expression] ']'
  | '[' expression {, expression}, others => <> ']'
null_array_aggregate ::= '[' ']'
!corrigendum 4.3.3(9)
Replace the paragraph:
An array_aggregate of an n-dimensional array type shall be written as an n-dimensional array_aggregate.
by:
An array_aggregate of an n-dimensional array type shall be written as an n-dimensional array_aggregate, or as a null_array_aggregate.
!corrigendum 4.3.3(26)
Insert after the paragraph:
the new paragraphs:
!comment The Implementation Permission of AI12-0212-1 and note of AI12-0061-1
!comment changed the following paragraph numbers (we use the Ada 2012 ones here):
!corrigendum 4.3.3(32/3)
Replace the paragraph:
10 In an array_aggregate, positional notation may only be used with two or more expressions; a single expression in parentheses is interpreted as a parenthesized expression. A named_array_aggregate, such as (1 => X), may be used to specify an array with a single component.
by:
10 In an array_aggregate delimited by parentheses, positional notation may only be used with two or more expressions; a single expression in parentheses is interpreted as a parenthesized expression. An array_aggregate delimited by brackets may be used to specify an array with a single component.
!corrigendum 4.3.3(36)
Replace the paragraph:
(1 .. 5 => (1 .. 8 => 0.0)) -- two-dimensional (1 .. N => new Cell) -- N new cells, in particular for N = 0
by:
(1 .. 5 => (1 .. 8 => 0.0)) -- two-dimensional [1 .. N => new Cell] -- N new cells, in particular for N = 0
!corrigendum 4.3.3(37)
Replace the paragraph:
Table'(2 | 4 | 10 => 1, others => 0) Schedule'(Mon .. Fri => True, others => False) -- see 3.6 Schedule'(Wed | Sun => False, others => True) Vector'(1 => 2.5) -- single-component vector
by:
Table'(2 | 4 | 10 => 1, others => 0) Schedule'(Mon .. Fri => True, others => False) -- see 3.6 Schedule'[Wed | Sun => False, others => True] Vector'(1 => 2.5) -- single-component vector
!corrigendum 4.3.3(40)
Replace the paragraph:
((1.1, 1.2, 1.3), (2.1, 2.2, 2.3)) (1 => (1.1, 1.2, 1.3), 2 => (2.1, 2.2, 2.3)) (1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3))
by:
((1.1, 1.2, 1.3), (2.1, 2.2, 2.3)) (1 => [1.1, 1.2, 1.3], 2 => [2.1, 2.2, 2.3]) [1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3)]
!ASIS
Not sure, as there is a minor syntax change.
!ACATS test
No additional tests needed.
!appendix

From: Randy Brukardt
Sent: Wednesday, January 23, 2019  6:17 PM

[Split from a thread in AI12-0212-1 - Editor.]

P.S. If we had made null aggregate a separate syntactic entity, we could
avoid some of the mess. That is, if we defined

    null_array_aggregate := '[' ']'

then we wouldn't need the textual definition of "null aggregate", we
wouldn't need the exception in 4.3.3(26), the 4.3.3(26.1) bullet would look
more similar to the others (and we could drop the AARM note), and so far as
I can tell, the only other paragraph that could need a bit of change would
be 4.3.3(20):

A subaggregate that is a string_literal is equivalent to one that is a
positional_array_aggregate of the same length, with each expression being
the character_literal for the corresponding character of the string_literal.

And here we could just use a TBH note, since it has been this way since
time-immemorial even though there never were any positional_array_aggregates
of length 0 or 1 until Ada 2020. Or we could clean up this old oddity by
mentioning a null_array_aggregate:

A subaggregate that is a string_literal is equivalent to one that is a
positional_array_aggregate of the same length (or a null_array_aggregate if
the length is zero), with each expression being the character_literal for
the corresponding character of the string_literal.

I didn't do this because changing the syntax seemed like a bit too much
change to do as "editorial". (Note this is how null container aggregates are
handled.)

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

From: Tucker Taft
Sent: Wednesday, January 23, 2019  9:52 PM

Might it be simpler to define "null_aggregate" in one place, and use it for 
both array aggregates and container aggregates?

In any case, I agree with your moving the definition of the bounds of a 
multidimensional null aggregate to a more appropriate place.

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

From: Randy Brukardt
Sent: Thursday, January 24, 2019  1:40 PM

> Might it be simpler to define "null_aggregate" in one place, and use 
> it for both array aggregates and container aggregates?

I thought of that, but it doesn't work well, because there are many rules that 
use the syntactic term "array_aggregate", and those (like the applicable index 
constraint) need to apply to a null array aggregate. We could try to say 
something like "a null_aggregate of an array type is a array_aggregate", but 
that's weird (we don't usually try to amend the meaning of syntax terms), and 
it increases the wording needed (I didn't check the containers wording, but 
I'd expect some similar issue to arise).

Changing all of the wording to use an English term rather than syntax would be 
way too much churn (there are more than twenty such paragraphs).

Probably the sweet spot is null_array_aggregate (which would, of course, be an 
array_aggregate) rather than having to use wording to separate it from 
positional_array_aggregate in the bounds rules. Should I write something like 
this up (later)?

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

From: Tucker Taft
Sent: Thursday, January 24, 2019  6:37 PM

...
> I thought of that, but it doesn't work well, because there are many 
> rules that use the syntactic term "array_aggregate", and those (like 
> the applicable index constraint) need to apply to a null array aggregate.

Couldn't we write:

   array_aggregate ::= positional_array_aggregate | named_array_aggregate

   positional_array_aggregate ::=
         (...)
      |  [...]
      | null_aggregate

  null_aggregate ::= '[' ']'

That would seem to make it clear that one legal syntax for a 
positional_array_aggregate is null_aggregate.

...
> Probably the sweet spot is null_array_aggregate (which would, of 
> course, be an array_aggregate) rather than having to use wording to 
> separate it from positional_array_aggregate in the bounds rules. 
> Should I write something like this up (later)?

See my suggestion above.  I realize I am probably missing something.

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

From: Randy Brukardt
Sent: Thursday, January 24, 2019  7:07 PM

> That would seem to make it clear that one legal syntax for a 
> positional_array_aggregate is null_aggregate.

We could but it doesn't help any of the wording.

...
> > Probably the sweet spot is null_array_aggregate (which would, of 
> > course, be an array_aggregate) rather than having to use wording to 
> > separate it from positional_array_aggregate in the bounds rules.
> > Should I write something like this up (later)?
> 
> See my suggestion above.  I realize I am probably missing something.

Yup. So far as I can tell, the only places where positional_array_aggregate 
is significant is in the equivalence for string literals and in the bounds 
of positional_array_aggregate.

But, in the latter, we don't actually *want* a null aggregate to be treated 
the same as a positional_array_aggregate. And in the former, we have always 
allowed null strings and singleton strings even though there never was such 
a thing for positional_array_aggregates. So we don't really need to change 
that now, either.

Every other rule is either on all array_aggregates or specific to 
named_array_aggregates.

So, there is no advantage to having null_array_aggregate included in 
positional_array_aggregate (regardless of *how* its included), and depending 
on your view of the string literal rule, it could be a negative. (I'd 
probably change the string literal rule to explicitly include the 
null_array_aggregate case, just so we don't have that reach anymore, but 
that's clearly not required.)

The point of the syntax change that I considered too much for an editorial 
review is to get it out of positional_array_aggregate altogether. If I was 
going to leave it in positional_array_aggregate, I could justify that, but 
it doesn't help the wording much. I'd rather help the wording more, or not 
bother.

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

From: Tucker Taft
Sent: Saturday, January 26, 2019  6:15 PM

Would things be simplified if we changed the wording slightly, as follows, 
where we leave the null aggregate (implicitly) within the first paragraph, 
but have an extra rule that is only for a null aggregate that is 
representing an aggregate for a multidimensional array type:

"For a positional_array_aggregate Redundant[(or equivalent string_literal)] 
without an others choice, the lower bound is that of the corresponding index 
range in the applicable index constraint, if defined, or that of the 
corresponding index subtype, if not; in either case, the upper bound is 
determined from the lower bound and the number of expressions Redundant[(or 
the length of the string_literal)];

{For a null aggregate for a multidimensional array type, bounds for each 
dimension are determined as for a positional_array_aggregate with zero 
expressions for each dimension;

  AARM Reason: We need a separate rule to describe what happens for a
  multidimensional null aggregate; the single dimension case directly follows
  from the positional_array_aggregate definition.}"

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

From: Randy Brukardt
Sent: Sunday, January 27, 2019  3:45 PM

That's where I started, but that leaves these two bullets overlapping in the 
null aggregate multidimensional case (both bullets appear to apply). We could,
I guess, leave it to common sense that the more specific bullet is the one to 
use, but it would be better to make it clear.

I then tried:

For a positional_array_aggregate Redundant[(or equivalent string_literal)] 
without an others choice {that is not a null aggregate for a multidimensional 
array type}, the lower bound is that of the corresponding index range in the 
applicable index constraint, if defined, or that of the corresponding index 
subtype, if not; in either case, the upper bound is determined from the lower 
bound and the number of expressions Redundant[(or the length of the 
string_literal)];

{For a null aggregate for a multidimensional array type, bounds for each 
dimension are determined as for a positional_array_aggregate with zero 
expressions for each dimension;
 
  AARM Reason: We need a separate rule to describe what happens for a
  multidimensional null aggregate; the single dimension case directly
  follows from the positional_array_aggregate definition.}

But the exclusion text is a real mouthful, so I simplified it to what I have.

Anyway, I thought it was better to separately define null_array_aggregate
because:
   (1) It's more like the container_aggregate presentation;
   (2) It eliminates the need to define the term "null aggregate";
   (3) It eliminates any need to mess with the positional_array_aggregate 
       bullet.
The downside is that it leaves the old handwaving about null string literals, 
but I suppose that's tolerable (we've tolerated it for at least 23 years, we 
can keep tolerating it).

If you don't agree, that's fine, it's not that big of an improvement. That's 
why I asked rather than just doing it. But I don't think it is possible to 
do better outside of that than what I already proposed for the wording.

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

From: Tucker Taft
Sent: Sunday, January 27, 2019  5:23 PM

OK, your approach of defining null_array_aggregate seems like the right 
solution.

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

From: Randy Brukardt
Sent: Friday, January 25, 2019  4:51 PM

Should some of the examples in 4.3.3 be redone to use [] instead of ()? It 
seems that there should be some examples showing that use (esp. if we want 
to think of it as preferred in new code).

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

From: Gary Dismukes
Sent: Friday, January 25, 2019  5:21 PM

Definitely.

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

From: Randy Brukardt
Sent: Friday, January 25, 2019  6:22 PM

I think I've got a volunteer!!! ;-)

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

Questions? Ask the ACAA Technical Agent