AI22-0005-1
!standard 6.6 (6) 21-11-11 AI22-0005-1/00
!class confirmation 21-11-11
!status received 21-11-11
!priority Low
!difficulty Easy
!qualifier Omission
!subject Editorial comments on AARM 2022
This AI serves as a holder for editorial comments on AARM-only annotations. This AI serves the same purpose as AI95-00114 did for Ada 2005, AI05-0005-1 did for Ada 2012, and AI12-0005-1 did for Ada 2022. Because the AARM has no official status as far as ISO is concerned, these will be considered low priority.
If a change cross-references this AI, find it in the Appendix below.
From: Niklas Holsti
WG 9 Review issue #167 - May 21, 2021
In this "Ramification" [4.9(13.b) - Editor.], the last case, "when specifying
the value of a discriminant ...", is no longer exactly true, because a
nonstatic value is now allowed if the value has a static subtype that governs
the variant part, RM 4.3.1(17/5).
****************************************************************
From: Randy Brukardt
WG 9 Review issue #167 - May 25, 2021
You are correct. Moreover, this note reads as if this is a complete list of
places where static expressions are required. But there has been no
maintenance of this list in Ada 2005, Ada 2012, or Ada 202x, and it is almost
certainly missing some constructs. It would be better to reduce it to a few
interesting cases as examples, because no one is ever going to remember to
maintain a list like this, (Rather, the complete list should be in the index
as "static expression, required", but that's another can of worms at this late
date - trying to find all of the places would be a pain.)
Anyway, I replaced the entire note with:
The language requires a static expression in a number_declaration, a numeric
type definition, certain representation items, and a number of other places.
If someone would like to develop a complete list of current places, I'd be
happy to put index entries in for them all. In that case, I'd add to the above
" See 'static expression, required' in the index for a complete list of
places".
****************************************************************
From: Tucker Taft
WG 9 Review issue #167 - May 27, 2021
I would defer the new index entry to the next revision. I would change
"places" to "contexts" in your new wording.
****************************************************************
From: Randy Brukardt
WG 9 Review issue #167 - May 27, 2021
I've marked this "deferred" so we remember to add the missing index entries.
****************************************************************
From: Steve Baird (privately)
Sent: Wednesday, August 24, 2022 7:16 PM
I didn't find an index entry for C_Pass_By_Copy .
****************************************************************
From: Randy Brukardt (privately)
Sent: Monday, November 25, 2024 8:47 PM
Nor for any other Annex B conventions. 6.3.1 conventions are indexed under "calling convention", so that's what I did for the Annex B ones as well. And added a "see also" to the index for "convention".
P.S. Yes, this is a bit late of a reply. :-)
****************************************************************
From: Randy Brukardt
In part from issue #19 - September 2, 2022
The profiles defined all should be indexed like "profiles, Ravenscar"
(similarly to restrictions).
****************************************************************
From: Steve Baird
Sent: Wednesday, April 19, 2023 (privately)
Are we missing something in
AARM Reason: For a function that has a parameter of T or access T, a blanket
rule in 13.1.1 requires the function to be a primitive operation of T, the
wording about the same declaration_list is redundant in that case.
? Perhaps something like
AARM Reason: For a function that has a parameter of T or access T (so a blanket
rule in 13.1.1 requires the function to be a primitive operation of T) the
wording about the same declaration_list is redundant.
would be better.
This wording occurs twice in the AI.
****************************************************************
From: Randy Brukardt
Sent: Friday, April 21, 2023 (privately)
How about:
AARM Reason: For a function that has a parameter of T or access T, a blanket
rule in 13.1.1 requires the function to be a primitive operation of T, so the
wording about the same declaration_list is redundant in that case.
[Editor's note: Fix both of the AARM notes in AI22-0002-1 (After
AARM 4.1.6(3.b/3) and AARM 5.5.1(8.a/3)).]
I suspect this is what was meant to be written. The point is that the blanket
rule makes the wording redundant in this particular case. We have the case
first, the mention of the blanket rule, and finally the consequence.
One could imagine fully rewriting these notes to reorder the parts, but I haven't
found anything that works better.
Since AI22-0002-1 is WG 9 approved, I'll put this wording fix into AI22-0005-1
(the AARM note AI). No ARG action is needed.
****************************************************************
From: Steve Baird (privately)
Sent: Friday, June 23, 2023 6:23 PM
The No_Unchecked_Conversion restriction moved to Annex J when
the No_Dependence restriction was introduced.
Given that, does H.4(1.a) need revision?
Note that the restrictions are absolute. If a partition has 100 library
units and just one needs Unchecked_Conversion, then the pragma cannot be
used to ensure the other 99 units do not use Unchecked_Conversion.
This no longer seems like the best example because it is no longer clear what
we mean by "the pragma". Is it a pragma defined in Annex J, or is it a
No_Dependence pragma, or ... ?
But perhaps this is fine or at least insufficiently broken to warrant any action.
What do you think?
****************************************************************
From: Randy Brukardt (privately)
Sent: Friday, June 23, 2023 11:25 PM
Shouldn't we just say "a Restrictions pragma" rather than "the pragma"?
****************************************************************
From: Steve Baird (privately)
Sent: Sunday, June 25, 2023 3:41 PM
I like your "a Restrictions pragma" idea.
My second choice is to do nothing.
****************************************************************
From: Github issue #66, Tucker Taft
Sent: September 7, 2023
Section A.8.2, File Management, has useful descriptions of several operations
applicable to almost all kinds of files. But these appear nowhere in the Index
of the RM. That seems like an oversight.
****************************************************************
From: Github issue #66, Randy Brukardt
Sent: September 28, 2023
This isn't really a "bug report", since the index is non-normative. Rather, it
is handled through the informal AARM update process. I've added this topic to
AI22-0005-1 where all of the AARM fixes live, and closed this topic.
****************************************************************
From: Github issue #66, Randy Brukardt
Sent: September 6, 2024
Having looked at this more carefully, this isn't an "oversight" but rather a
consequence of how the language-defined subprograms are indexed.
In particular, language-defined entities are indexed when they appear as
language-defined specifications. For instance, "Create" is indexed where it
appears in the specification of Text_IO. Language-defined entities are NEVER
indexed where the descriptive text is located.
That doesn't make a lot of difference for most subprograms, since those things
are found in the same clause, but there are some cases (like most of the I/O
operations, not just A.8.2, but also all of the other operations of
Sequential_IO, Direct_IO, and Text_IO; it also happens for the shared
operations for map and set containers) where the descriptive text is found in
a different subclause.
I believe the original indexing was chosen as not all language-defined packages
have full descriptive text including a specification (for instance, the
Ada.Strings packages do not repeat the subprogram definitions with the
descriptive text), while all language-defined packages certainly have a
specification. Additionally, the indexing operations use the surrounding
package to give a reference to the associated package, that isn't reliably
available for descriptions and wouldn't be available at all for operations
that have shared descriptions, such as those in A.8.2 and the map and set
containers.
It would make sense to change the indexing to primarily work from the
descriptions rather than the specifications. But that would be a lot of work,
as there are more than 1500 subprograms defined, and one would have to decide
which ones could be moved and which ones could not (certainly, they all
cannot be moved to the descriptions because we want to index complete
specifications). And as noted above, not all of the descriptions can use
the existing indexing operations; either additional operations would have
to be defined or one would have to figure out ways to use existing operations.
The fact that a number of different operations would be needed would also
prevent any rote changes; everything would have to be considered carefully.
Given that a general change is too expensive to do (especially in our new
reality of unfunded work), the only remaining question is whether A.8.2 should
be handled in some special way. We could do that, but I don't see any reason
to treat it differently than A.10.6 or A.18.4 or A.18.6 (or, for that matter,
the one package sections of A.8.3, A.8.5, and A.10.3-A.10.12). All of those
cannot be found directly from the existing indexes, you have to do some sort
of search to find the descriptive material. (And really, you have to do that
for all subprograms, but most are on the same page.) That puts us back to the
"too much work" answer.
As such, I'm not going to do anything with this issue (other than record it
as noted above).
****************************************************************
From: Github issue #70, Steve Baird
Sent: September 28, 2023
We've currently got: [In AI22-0067-1 - Editor.]
Add after 4.3.3(31):
The nominal subtype of an array_aggregate (other than a subaggregate)
is constrained by the values defined for its bounds and those of any
subaggregates.
For AARM, add after that:
To be honest:
If an array_aggregate has more than one subaggregate corresponding to
the same index, then the bounds of the first such subaggregate determine
the constraint of the nominal subtype of the array_aggregate
for that index.
Given the current language definition (and, in particular, the RM's uses of
"nominal subtype"), there does not appear to be any need to mention the
case where some but not all of the subaggregates corresponding to a given
index have static bounds. One could imagine something like "use static
bounds if they are available; otherwise take the bounds from the first
subaggregate" but this does not appear to be necessary.
****************************************************************
From: Github issue #70, Randy Brukardt
Sent: September 29, 2023
The proposed note seems like unjustified overspecification to me. We know that
the bounds of all such subaggregates have to be the same, if not, Constraint_Error
will be raised. If that happens, nothing that depends upon the nominal subtype
can be executed. So, it doesn't matter which set of bounds is selected, and we
should let the implementation pick whatever is convenient for it. Ergo, I think
a better note would be something like:
Ramification: If an array_aggregate has more than one subaggregate
corresponding to the same index, then Constraint_Error will be raised unless
all of the bounds of such subaggregates are the same. If Constraint_Error
is raised, no code that could depend upon the details of the nominal subtype
of the aggregate could be executed. Therefore, the implementation can use
whichever such subaggregate is convenient to determine the bounds of the
nominal subtype.
****************************************************************
From: Github issue #70, Steve Baird
Sent: October 2, 2023
I (now) like Randy's idea that the implementation simply gets to pick one of
the candidates, but we don't specify which one since the choice doesn't really
matter. I'd still rather see some mention of this in an AARM note, as opposed
to saying nothing, since otherwise it looks like a hole (even if it isn't). I
don't feel strongly about it.
****************************************************************
From: Github issue #70, Tucker Taft
Sent: October 2, 2023
> I (now) like Randy's idea that the implementation simply gets to pick one
> of the candidates, but we don't specify which one since the choice doesn't
> really matter.
Agreed.
> I'd still rather see some mention of this in an AARM note, as opposed to
> saying nothing, since otherwise it looks like a hole (even if it isn't).
I agree that there is a danger that all those Steve Baird clones out there
will be hammering on us with ARG GitHub issues if we don't add the note. ;-)
> I don't feel strongly about it.
But strongly enough, it seems, so we should add the note!
****************************************************************
From: Randy Brukardt
Direct to this AI; Wednesday, October 11, 2023
AI22-0006-1 has AARM notes AARM 4.1.6(3.b/3) and AARM 5.5.1(8.a/3),
which contain the supposed syntax term "declaration_list". But there is no
such syntax; there is a defined term "declaration list" and that is what is
meant by these notes. That has been corrected in the RM draft.
****************************************************************
From: John Barnes (privately)
Sent: Monday, October 23, 2023 9:11 AM
I am toiling with updating my wretched book. I noticed that K 34.1/5 says
Iterator_View An alternative type to used for container element iterators. See 5.5.1.
It needs a be before used.
****************************************************************
From: Randy Brukardt
Annex K is a generated annex; the original source is found in the AARM, in this
case 5.5.1(9.d/5). We need to correct that note to correct the annex; thus the
change is recorded in the AARM AI (AI22-0005-1).
****************************************************************
From: Christoph Grein
Sent: Thursday, November 16, 2023 8:25 AM
!topic ... allowed by the Global aspect of{ }A, then...
!reference Ada 2022 AARM13.13.2(37.a/5)
!from Christoph Grein 2023-11-16
!discussion A funny coincidence with my previous mail - the very same paragraph
number in a different subclause.
****************************************************************
From: Christoph Grein
Sent: Thursday, November 16, 2023 8:25 AM
!topic Unfortunate wording
!reference Ada 2022 AARM13.13.1(37.a/5)
!from Christoph Grein 2023-11-16
!discussion
Reason: The Streams.Storage.Bounded package is provided in order to make
available an alternative to the Streams.Storage.Unbounded package *which
gives more predictable memory usage*.
I know what is meant (do I?) but I think the wording is unfortunate because
the part italicized above at first sight seems to reference the Unbounded
package.
****************************************************************
From: Tucker Taft
Sent: Thursday, November 16, 2023 8:48 AM
Agreed. Better might be:
Reason: The Streams.Storage.Bounded package is provided as an alternative
to the Streams.Storage.Unbounded package, but with more predictable memory
usage.
****************************************************************
From: Vincent Marciante
Sent: Thursday, November 16, 2023 9:24 AM
How about:
The Streams.Storage.Bounded package is provided in order to make available
an alternative means to store streams which has more predicable memory usage
than the Streams.Storage.Unbounded package.
****************************************************************
From: Randy Brukardt
Sent: Thursday, November 16, 2023 9:26 PM
I don't really like either of these, but something better seems doesn't seem easy to come up with.
Tucker suggested:
>Reason: The Streams.Storage.Bounded package is provided as an alternative
>to the Streams.Storage.Unbounded package, but with more predictable memory
>usage.
The "but" here is clunky, as there really isn't anything that we're opposing to.
Without it, the original problem returns.
Vincent suggested:
>The Streams.Storage.Bounded package is provided in order to make available
>an alternative means to store streams which has more predicable memory usage
>than the Streams.Storage.Unbounded package.
We've never talked about "storing streams", and that's not an accident. It's not
the streams that are getting stored, but rather the data sent to them.
These packages are just an implementation of streams that don't use any files.
Thus, they are just an in-memory implementation -- but we don't use that
description, either, because "memory" isn't well-defined (in an RM sense).
Probably we need a more aggressive reordering:
The alternative package Streams.Storage.Bounded provides more predictable memory
usage than the Streams.Storage.Unbounded package.
Maybe even drop the alternative and explain the trade-offs better:
The package Streams.Storage.Bounded provides more predictable memory usage than
the Streams.Storage.Unbounded package, at the cost of needing to determine a
maximum number of stream elements that can be stored.
****************************************************************
From: Jean-Pierre Rosen
Sent: Friday, November 17, 2023 3:57 AM
> I don't really like either of these, but something better seems doesn't seem
> easy to come up with.
Or a simple swap:
Reason: The Streams.Storage.Bounded package is provided in order to make
available an alternative, which gives more predictable memory usage, to the
Streams.Storage.Unbounded package.
****************************************************************
From: Tucker Taft
Sent: Friday, November 17, 2023 7:23 AM
Seems better. I still find "is provided in order to make available an alternative"
in the "department of redundancy department"... Also, the placement of the "which"
clause is still a bit awkward. How about:
Reason: As an alternative to the Streams.Storage.Unbounded package, the
Streams.Storage.Bounded package is available, which provides more predictable
memory usage.
****************************************************************
From: Christoph Grein
Sent: Friday, November 17, 2023 7:52 AM
My favorites in descending order:
Reason: The alternative package Streams.Storage.Bounded provides more
predictable memory usage than the Streams.Storage.Unbounded package.
We know this difference already from the container packages.
Reason: The package Streams.Storage.Bounded provides more predictable
memory usage than the Streams.Storage.Unbounded package, at the cost of
needing to determine a maximum number of stream elements that can be stored.
Reason: As an alternative to the Streams.Storage.Unbounded package, the
Streams.Storage.Bounded package is available, which provides more
predictable memory usage.
****************************************************************
From: Jeffery Carter
Sent: Friday, November 17, 2023 9:25 AM
> provides more predictable memory usage.
Does the ARM use "memory" now? It used to always use "storage" (as in these
pkg names).
****************************************************************
From: Randy Brukardt
Sent: Thursday, December 7, 2023 8:33 PM
We're talking about an AARM note, not the RM.
The latest AARM has 45 subclauses that use "memory" in some way (I didn't look
in detail how). This is contrasted to 91 subclauses that use "storage" in some
way (many of which are talking about storage pools or one of the packages that
have Storage in the name).
There doesn't seem to be a clear winner in terms of AARM notes, so I think the
principle of least change applies here. I left it as "memory".
****************************************************************
From: Randy Brukardt
Sent: Thursday, December 7, 2023 8:39 PM
>Seems better. I still find "is provided in order to make available an alternative"
>in the "department of redundancy department"...
I would have called it "verbal diarrhea". :-)
>... Also, the placement of the "which" clause is still a bit awkward. How about:
> Reason: As an alternative to the Streams.Storage.Unbounded package, the
> Streams.Storage.Bounded package is available, which provides more predictable
> memory usage.
I think we could dispense with "available", too. And the commas if we use "that"
rather than "which". So perhaps:
Reason: The Streams.Storage.Bounded package is provided as an alternative that
gives more predictable memory usage than the Streams.Storage.Unbounded package.
****************************************************************
From: Randy Brukardt
Sent: Thursday, December 7, 2023 8:55 PM
>My favorites in descending order:
> The alternative package Streams.Storage.Bounded provides more
> predictable memory usage than the Streams.Storage.Unbounded package.
I had forgotten that I had previously suggested this (the problem with reading
only the unread messages in the thread). This is better than my recent suggestion.
>We know this difference already from the container packages.
Right, but those occur after this subclause (so a linear reader will not have
encountered them yet). We try to avoid forward references as much as possible.
That's why I suggested (and used):
> The package Streams.Storage.Bounded provides more predictable memory
> usage than the Streams.Storage.Unbounded package, at the cost of
> needing to determine a maximum number of stream elements that can be stored.
I note that the phrase "more predictable memory usage" comes from A.18(5.j/3).
That note doesn't explain the trade-off, it seems reasonable to do so somewhere.
****************************************************************
From: Github issue #72, Tucker Taft
Sent: Friday, December 1, 2023
Exactly when should a dynamic subtype on an array subtype be invoked? In
particular, if the first subtype of an array type has a predicate such as:
type A1 is array (Positive range <>) of Integer
with Dynamic_Predicate => A'First = 1;
is it inevitable that you will get a predicate failure if you write a slice
of an array object of such a type with a low bound other than one? For example,
should the following succeed or fail:
X5 : A1 (1 .. 5);
X2 : A1 (1 .. 2) := X5 (3 .. 4);
I hope it would succeed. I would suggest that a slice is an object of a new
subtype of the type, without any predicate, and in any case, any predicate on
the first subtype of the array type doesn't apply. Otherwise, it could be very
hard to use such an array type.
Similarly, an aggregate of such a type could have something other than a low
bound of 1:
X3 : A1 (1 .. 3) := (2 => 2, 3 => 3, 4 => 4);
I believe this should also succeed.
The Ada RM defines subtype predicate checks as being associated with subtype
conversion (RM 3.2.4(31/5)), but there is no subtype conversion associated with
an aggregate or a slice as far as I can see, unless you explicitly write a
qualified expression. Note also that when the first subtype of an array type
is constrained, you can nevertheless do slicing and concatenation of objects
that do not satisfy the first subtype's constraint, since these operations
operate on the underlying type, rather than the first subtype.
[Editor's note: I've only included the most relevant parts of this Github issue
here.]
****************************************************************
From: Github issue #72, Steve Baird
Sent: Tuesday, December 5, 2023
FWIW, I agree with Tuck's reasoning and conclusions. With many language issues,
there are separate questions about what the RM says and what it should say.
Let's start with the latter. It has been well established since Ada83 that the
constraint (if any) of the first subtype of an array type is not checked for a
slice, an aggregate, or an actual parameter in a call to a predefined operator
such as "=" or "&". Given that constraint checking works that way (which
nobody is disputing), it would be very irregular if predicate checking worked
differently. And Tuck points out what the the RM does say (if only by omission)
is consistent with this interpretation. So a note clarifying this point would
probably be a good thing, but it would only be a clarification (as opposed to
a change to the language definition).
****************************************************************
From: Github issue #72, Randy Brukardt
Sent: Wednesday, December 6, 2023
The design of predicates was very intentional to be as close to "user-defined
constraints" as possible. The "omission" as Steve calls it was an intentional
design decision, to make it easier on both users and implementers (the latter
because they don't need to look for new places to make checks).
So I don't understand the point of this question. The RM clearly specifies
where checks are made (and certainly they're not made elsewhere), those places
match one's intuition about what one would want, so nothing seems wrong OR
unclear.
I was confused by Tucker's examples:
X3 : A1 (1 .. 3) := (2 => 2, 3 => 3, 4 => 4);
The Ada RM defines subtype predicate checks as being associated with
subtype conversion (RM 3.2.4(31/5)), but there is no subtype conversion
associated with an aggregate or a slice as far as I can see ...
There is of course a subtype conversion associated with the assignment, and
for most purposes that is indistiguishable from one of the slice or aggregate.
But I see that's not true for assignments into array objects, as the sliding
happens first. Again that is very clear in 4.6.
So, I don't see the need for even a ramification AI on this one. We don't
write notes that something not mentioned doesn't happen, in part because there
is an infinite number of such things.
Agreed? Can this topic be marked as adequately answered and closed??
****************************************************************
From: Github issue #72, Tucker Taft
Sent: Thursday, December 7, 2023
I guess I would like to see an AARM note. For example, we could augment
AARM 3.6(16.a/3) as follows:
Discussion: Although there is no nameable unconstrained array subtype in this
case, the predefined slicing and concatenation operations can operate on and
yield values that do not necessarily belong to the first array subtype. This
is also true for Ada 83. {Similarly, if a Dynamic_Predicate applies to the
first subtype of an array type, it is not checked on a slice or an aggregate
of the type, until it is converted to a subtype to which the predicate
applies.}
****************************************************************
From: Github issue #72, Randy Brukardt
Sent: sunday, December 10, 2023
OK, I've added this note change to AI22-0005-1. [This AI, editor.]
****************************************************************
From: Randy Brukardt
Sent: Wednesday, March 13, 2024 [Here only]
The second sentence of 6.5.1(4.b/5) needs a comma (it currently is a run-on
sentence):
If a nonreturning subprogram is renamed (anywhere){,} calls through the
new name still have the nonreturning semantics.
****************************************************************
!reference Ada 2022 AARM A.16.1(38.a/3)
!from Christoph Grein 2024-03-20
!topic If interpretation is needed, Directories.Full_Name can be {used} to
expand any shorthands [used] before calling Containing_Directory.
****************************************************************
From: Stephen Baird
Sent: Wednesday, April 3, 2024 3:45 PM [Privately]
In 13.13.1(8) in the case where the end of the stream is reached and the
value returned in Last is less than Item'Last, the RM doesn't say anything
about the remaining array elements.
It probably should say explicitly that the state of that final slice
Item (Last+1 .. Item'Last) upon return is unspecified, or that the incoming
value is preserved, or something (as opposed to saying nothing).
Do you think this warrants any sort of action?
****************************************************************
From: Randy Brukardt
Sent: Wednesday, April 3, 2024 10:07 PM [Privately]
Saying nothing is the *definition* of unspecified. If the standard doesn't say
anything, *of course* it is unspecified. It's only necessary to say something
is unspecified if that overrides some other explicit rule. I don't think that
is happening here.
Should it be something other than unspecified? In most cases, the incoming
value is going to be preserved. But is it worth saying that? I doubt it, I
can't think of an advantage to doing that, as the client must be prepared for
the entire object to be overwritten (one can't easily predict when the end
of a stream will be reached). Moreover, I can imagine having the underlying
system directly write into the buffer if it is the right size, as that would
avoid copying data around. We probably can't predict what the underlying
system will do. (CP/M is an obsolete example: it did all file I/O in 128 byte
chunks. The remainder was filled with whatever junk was in the buffer when
written. When reading, you'd get some random junk read (which would be
ignored, of course).
So I think it is best that it be unspecified.
>Do you think this warrants any sort of action?
No. I suppose we could add an AARM note, but it would be restating the
(fairly) obvious.
****************************************************************
From: Stephen Baird
Sent: Thursday, April 4, 2024 12:51 PM [Privately]
I still think an AARM note would be useful, just to clarify what was intended.
If the RM says nothing about some scenario, then it could be just an oversight.
But I don't feel strongly about it.
I asked this one because an AdaCore customer was confused about this point;
this wasn't just me channeling my inner Beneschan.
> So I think it is best that it be unspecified.
I agree.
>>Do you think this warrants any sort of action?
>No. I suppose we could add an AARM note, but it would be restating the
>(fairly) obvious.
I would support such a note, but (as noted above) I don't feel strongly about it.
****************************************************************
From: Randy Brukardt
Sent: Thursday, April 4, 2024 5:20 PM [Privately]
Tucker, do you agree with Steve about an AARM note in this case? If so, I can
put this thread into the AARM AI and add a note (no need for the full ARG to
get involved). If not, Steve can decide whether he wants to pursue it further
or not.
****************************************************************
From: Stephen Baird
Sent: Thursday, April 4, 2024 6:02 PM [Privately]
If it turns out that both of you feel that no action is needed, then that's
good enough for me.
****************************************************************
From: Tucker Taft
Sent: Thursday, April 4, 2024 7:18 PM [Privately]
An AARM note seems harmless. There are other places where Last is used as an
OUT parameter, such as in Get_Line. We say the following in A.10.7(19), so it
would seem OK to say something similar in 'Read (italics are mine):
procedure Get_Line(Item : out String;
Last : out Natural);
Reads successive characters from the specified input file and assigns them
to successive characters of the specified string. Reading stops if the end
of the string is met. Reading also stops if the end of the line is met
before meeting the end of the string; in this case Skip_Line is (in effect)
called with a spacing of 1. *The values of characters not assigned are not
specified.*
****************************************************************
From: Stephen Baird
Sent: Wednesday, May 15, 2024 1:52 PM [Privately]
Another one where the intent is clear, but it is less clear that the RM's
wording captures that intent.
I think there may be some places where the RM talks about the freezing point
of some entity where, strictly speaking, it needs to be talking about the
first freezing point of the entity.
In 13.14(2) we've got
The freezing of an entity occurs at one or more places (freezing points)
in the program text where the representation for the entity has to be
fully determined. Each entity is frozen from its first freezing point to
the end of the program text (given the ordering of compilation units
defined in 10.1.4).
So it is clear that an entity can have many freezing points and that the first
one has some special significance.
So how does this relate to 13.1.1(37)?
At the freezing point of the associated entity, the aspect_specification is elaborated.
Or 13.11(18)?
If the implementation cannot satisfy the request, Storage_Error is raised at the freezing
point of type T.
If you search the RM for "the freezing point", there are hits on 6 pages. Rather than
change all of those, I think it would be better to add some wording in 13.14 somehow
saying that *the* freezing point of an entity (as opposed *a* freezing point
of an entity) refers to the first freezing point of the entity.
Is any action warranted here? Perhaps the existing wording is sufficiently clear.
****************************************************************
From: Randy Brukardt
Sent: Wednesday, May 15, 2024 2:26 PM [Privately]
I suggest looping in Tucker on this one, as I'm on the fence. On one hand, the
meaning seems obvious, on the other hand, there does seem room for confusion.
"The freezing point" is the point at which the entity is actually frozen, that
happens at some "freezing point" of the entity. It seems that the terminology
is too similar for comfort. So maybe we do need to do something.
****************************************************************
From: Tucker Taft
Sent: Wednesday, May 15, 2024 3:52 PM [Privately]
I see no chance for confusion so no change to the RM seems necessary. A
to-be-honest AARM note would be more than adequate if you are worried.
****************************************************************
From: Stephen Baird
Sent: Wednesday, May 15, 2024 4:40 PM [Privately]
I certainly agree that nothing more than a TBH AARM note is needed.
Like Randy, I am somewhat on the fence regarding whether anything at all is
needed. Perhaps this falls into the "insufficiently broken" category.
****************************************************************
From: Randy Brukardt
Sent: Wednesday, May 15, 2024 7:33 PM [Privately]
How about:
AARM to be honest: Elsewhere in this Reference Manual the phrase "the freezing
point" is used to describe the point where an entities properties are
determined. This is the same as the first freezing point as used in this subclause.
****************************************************************
From: Tucker Taft
Sent: Thursday, May 16, 2024 3:22 AM [Privately]
Works for me.
****************************************************************
From: Stephen Baird
Sent: Thursday, May 16, 2024 12:30 PM [Privately]
typo: Entities => Entity's
Another alternative:
AARM to be honest: Strictly speaking, references elsewhere in this
Reference Manual to "the freezing point" of an entity (as if the
entity has only one freezing point) refer to the first freezing
point of the entity.
****************************************************************
From: Tucker Taft
Sent: Saturday, May 18, 2024 4:41 AM [Privately]
Either is fine with me. By the way, how many angels did you see dancing
on the head of that pin? ;-)
****************************************************************
From: Stephen Baird
Sent: Tuesday, July 2, 2024 5:43 PM [Privately]
In 3.5(56.d), is this grammatically correct?
"... the sizes of out parameters could be different whether or not a Default_Value
is specified (see 6.4.1)."
Should that be something like "... could be different depending on whether or not ..."?
****************************************************************
From: Randy Brukardt
Sent: Wednesday, July 3, 2024 11:07 PM [Privately]
It's OK to me, but perhaps not others. Anyone else want to weigh in on this??
****************************************************************
From: Tucker Taft
Sent: Thursday, July 4, 2024 6:44 AM [Privately]
In my view the current sentence is grammatically correct. The more interesting
question is whether it is semantically correct. What it says now (to me!) is
that the sizes of OUT parameters could be different *independent* of whether
or not there is a Default_Value specified. Your rewording indicates that the
OUT parameter size is *dependent* on whether or not Default_Value is specified.
The sentence refers to 6.4.1, where we have the AARM annotation:
Implementation Note: This rule means that out parameters of a subtype T with a
specified Default_Value need to be large enough to support any possible value
of the base type of T. In contrast, a type that does not have a Default_Value
only need support the size of the subtype (since no values are passed in).
This seems to indicate that the size could be different *because* of the
Default_Value specification, so I agree with your rewording, but not for
grammatical reasons ... ;-)
****************************************************************
From: Randy Brukardt
Sent: Thursday, July 4, 2024 11:52 PM [Privately]
Since it always meant what Steve's rewording says, it apparently IS
grammatically incorrect (since it says something different than meant). I'll
put it on the AARM AI list to fix.
****************************************************************
From: Stephen Baird
Sent: Thursday, July 11, 2024 2:55 PM [Privately]
Back when we added the rule that a target_name causes the LHS to be a complete
context, should AARM 5.2(4.a) have been updated? That note says that its
conclusion follows from the fact that an assignment statement is a complete
context, but that's wrong. The conclusion follows from the fact that an
assignment statement is (in the absence of a target_name) an *innermost*
complete context. In particular, the conclusion is wrong if a target_name is
involved.
I understand that this is all wording that you didn't touch and an issue that
you didn't introduce. Blame heat vision.
****************************************************************
From: Randy Brukardt
Sent: Thursday, July 11, 2024 9:37 PM [Privately]
Well, it's outright wrong, and that needs fixing regardless of what the
current topic is. I've put this into the AARM AI, and "fixed" it by adding
a sentence after the example.
"Note that there are different rules if a target name symbol is used in
the assignment_statement (see 5.2.1). so this is not true in that case."
****************************************************************
From: Github issue #103, Gustavo A. Hoffman
Sent: sunday, July 21, 2024
In the Annotated Ada RM 3.7 (10.b/3), we read: "Ramification: A (nonformal)
limited private type can always have a default for an access discriminant,
because having the default itself makes the type immutably limited. Such a
private type must necessarily have a full type with the same access
discriminant with a default, and thus the full type will always be immutably
limited (if legal)."
This might be potentially misleading — even with the "(if legal)" indication
— as one could understand that this part:
because having the default itself makes the type immutably limited
indicates that having a default for an access discriminant is enough to
consider the type immutably limited.
In a separate conversation with Tucker Taft, he mentioned that 10.b/3 should
probably say:
..., and thus the full type will need to be defined so that it is
immutably limited, or else the access discriminant with a default will
be illegal on the full type.
****************************************************************
From: Github issue #103, Jeff Cousins
Sent: Monday, July 22, 2024
> This might be potentially misleading — even with the "(if legal)"
> indication — as one could understand that this part:
>
> because having the default itself makes the type immutably limited
>
> indicates that having a default for an access discriminant is enough
> to consider the type immutably limited.
That's how I would have interpreted it at first reading.
****************************************************************
From: Github issue #103, Randy Brukardt
Sent: Wednesday, August 21, 2024
>This might be potentially misleading — even with the "(if legal)" indication
> — as one could understand that this part:
>
> because having the default itself makes the type immutably limited
This part looks redundant to me; we're immediately going to explain why this
is the case. Indeed, it looks like something I would have written, where I
repeat the same point multiple ways. Some editing seems necessary, probably
just drop this part altogether. If we do that, the rest doesn't really need
changing, although it never hurts to be clearer.
>In a separate conversation with Tucker Taft, he mentioned that 10.b/3 should probably say:
>
> ..., and thus the full type will need to be defined so that it is immutably limited,
> or else the access discriminant with a default will be illegal on the full type.
This looks a bit redundant, too. We've already mentioned "access discriminant
with a default" in this sentence and the preceding one, we hardly need to keep
saying it.
So I suggest:
Ramification: A (nonformal) limited private type can always have a default for
an access discriminant. Such a private type must necessarily have a full type
with the same access discriminant with a default, and thus the full type will
need to be defined so that it is immutably limited, or else the full type will
be illegal.
Since this is an update to an AARM note, it doesn't require any ARG action.
I'll store this thread into AI22-0005-1 (where AARM notes and non-normative
stuff like index entries get recorded), and make the change to the draft AARM.
****************************************************************
From: Github issue #103, Tucker Taft
Sent: Wednesday, August 22, 2024
Randy, your proposed rewording is fine with me.
****************************************************************
From: Stephen Baird
Sent: Tuesday, July 30, 2024 2:58 PM [Privately]
Should the list of RM index entries for Program_Error mention 4.5.2(24.1):
If the primitive equals operator for an untagged record type is abstract,
then Program_Error is raised at the point of ...
?
****************************************************************
From: Randy Brukardt
Sent: Tuesday, July 30, 2024 5:34 PM [Privately]
Yes, I suppose it should be included, something like "Program_Error, raised
by calling an abstract equality". I'll put this into the AARM AI (as this is
non-normative, and just fix it. (Indeed, I've already done so.)
****************************************************************
From: Randy Brukardt
Sent: Friday, August 2, 2024
John Barnes notes that AARM 10.2(34.f) says that we do not use the term
"main program", preferring "main subprogram". However, AARM 10.2(7.f) uses the
term; it should talk about the "main subprogram" instead.
Note: A couple of occurrences in normative wording are handled in AI22-0114-1.
****************************************************************
From: Steve Baird
Sent: Wednesday, August 7, 2024 2:24 PM
4.10(47) says
For a string type, implementations may produce an image corresponding to a
string literal.
So for something like
type Enum (Aaa, Bbb, Ccc, 'D');
type A_String_Type is array (Positive range <>) of Enum;
Obj : A_String_Type := (1 .. 3 => Aaa);
Img : constant String := Obj'Image;
what does that implementation permission permit?
Even in the case of a predefined string type, are there related issues in the
case of an array value that could not be represented in source code as a
string literal?
Would an AARM note clarifying the situation be appropriate?
****************************************************************
From: Randy Brukardt
Sent: Wednesday, August 7, 2024 11:59 PM
...
> what does that implementation permission permit?
Not much! :-) I think it is implicit that we are talking about string literals
as defined in the RM, so only "DDD" is a legal string literal. So in this
case, Obj'Image cannot use the string literal form.
>Even in the case of a predefined string type, are there related issues
>in the case of an array value that could not be represented in source code as a
>string literal?
Yes, I would think so.
>Would an AARM note clarifying the situation be appropriate?
It seems obvious to me. The permission says "string literal", not "something
vaguely resembling a string literal". That means by definition that it can't
be used for all possibilities if the component type contains unprintable
characters. Just as you can't do use a string literal to create all possible
Strings.
I suppose one could explain this in an AARM Ramification, but since AdaCore
doesn't read the AARM by policy (although that was a RKBD policy, so it might
be gone these days) dunno if it matters. What would you suggest? What does
Tucker think? Enquiring minds want to know.
****************************************************************
From: Steve Baird
Sent: Thursday, August 8, 2024 2:09 PM
I agree that the intent is obvious, but we try not to rely on Dewar's rule in
defining the language.
Perhaps we just add a small modifier to the existing permission, something like
" ... may produce an image corresponding to a string literal (when possible)."
Would that also clarify the behavior in the case where non-graphic characters
are involved? For example, I think that if X is a String object with at least
one non-graphic character component, this permission is not intended to allow
Standard.String'Image (X) to yield the same value as
'"' & X & '"' ,
****************************************************************
From: Randy Brukardt
Sent: Thursday, August 8, 2024 11:14 PM
I don't agree that any Dewar rule is needed here. The term "string literal" is
well-defined by the RM, and there is no indication here that any extension is
imagined. You have to apply a Dewar-like rule to get any such imagination (I
say Dewar-like because the actual words make plenty of sense.)
I don't have a problem with adding an AARM Ramification to make it clear that
this does not allow just sticking quotes around the contents of a string type,
but I don't see any need to fiddle with the permission. It's already a
permission, after all, it is allowing something not otherwise allowed, but it
clearly doesn't extend beyond the actual words. An AARM note would have the
effect of making it clear that we knew what we were doing when we wrote the
permission.
Feel free to suggest an AARM note.
****************************************************************
From: Steve Baird
Sent: Friday, August 9, 2024 5:04 PM
Add after 4.10(47):
AARM note:
If the value of some component of the array argument is not that of a
defining_character_literal of the string type's component type, then
no such "corresponding to a string literal" image exists.
****************************************************************
From: Steve Baird
Sent: Tuesday, August 20, 2024 5:58 PM
The index contains the RM's only hyphenated use of "multi-dimensional".
****************************************************************
From: Randy Brukardt
Sent: Wednesday, August 21, 2024 8:33 PM
It was that way in Ada 95.
****************************************************************
From: Github issue #107, Reed Hayden
Sent: Wednesday, September 18, 2024
The function Ada.Strings.Hash is defined in A.4.9 (2/5).
Additionally A.4.7 (29/3) and A.4.8 (29/3) note that there are corresponding
functions Ada.Strings.Wide_Hash and Ada.Strings.Wide_Wide_Hash.
The function Ada.Strings.Hash is located in Annex Q under Q.3 Language-Defined Subprograms.
However, Ada.Strings.[[Wide_]Wide_]Hash is located in Q.1 Language-Defined Packages.
I believe the functions should be moved to the correct Annex Subclause.
This mismatch also exists for the functions Ada.Strings.[Wide_]Wide_Hash_Case_Insensitive.
****************************************************************
From: Github issue #107, Tucker Taft
Sent: Wednesday, September 18, 2024
Thanks for the bug report!
****************************************************************
From: Github issue #107, Randy Brukardt
Sent: Wednesday, October 23, 2024
The same mistake also occurs for functions Ada.Strings.[Wide_]Wide_Equal_Case_Insensitive.
At least I'm consistent. :-)
Indexing is considered non-normative, so it is recorded in AI22-0005-1 and just
fixed in the working draft (which I have already done). No ARG action is required,
so I have closed this issue.
****************************************************************
From: Github issue #83, Randy Brukardt
Sent: Thursday, January 9, 2025
[Editor's note: There is a lot of additional discussion in the Issue.]
Richard and I have been continuing this discussion privately for much of the
last 4 hours. Here are a couple of points from that discussion that is is worth
recording here:
Cursors are naturally unordered. There is no meaningful order between two
cursors that designate different container objects (nor between Null_Cursor and
some other cursor). It could make sense to talk about the order between two
cursors that designate the same container object, but the language never does
that.
In any case, the "<" in the Ordered_Maps and Ordered_Sets provides an order to
any non-null cursor passed in, even those that could not have an order because
they designated different cursors. As such, it is better thought of as a
shorthand for comparing the keys (for maps) or elements (for sets) designated
by the cursors. Perhaps a different definition would have been better, but it
is clearly too late try to reimagine the meaning of the "<" operation -- it
would be introducing a behavior change that could break existing, working code.
The second point is that we have a language design principle that
language-defined sets of relational ordering operators always maintain the
usual relationships between the operators. We want the language to show good
practice for redefining operators, and not confuse the casual reader of code.
These relationships are, for any A and B:
(A < B or A = B) is the same as (A <= B)
(A > B or A = B) is the same as (A >= B)
(A < B) is the same as (not (A >= B))
(A > B) is the same as (not (A <= B))
However, if A and B are equivalent but not equal keys (or elements), no matter
how you define <= and >=, you cannot preserve all four of these relationships.
In such cases, we don't define any or all of the operators in order to avoid
breaking this "good taste in relational operators" principle.
Adding "<=" and ">=" would break this principle for cursors, unless we somehow
required the cursors to be from the same container. We don't currently have
such an operation available to use in a precondition; the operation that we
typically use in preconditions requires the name of the container object,
which obviously would be hard to obtain in an operator symbol (there are
no three parameter operator symbols). And such operations would then be
inconsistent with the cursor vs key versions.
****************************************************************
From: Github issue #83, Niklas Holsti
Sent: Friday, January 10, 2025
Perhaps a short summary of this issue could be put in the AARM as
rationale for not having the "<=" and ">=" operators.
[Editor's note: Two others concurred with that opinion.]
****************************************************************
From: Github issue #83, Randy Brukardt
Sent: Thursday, January 23, 2025
OK, as requested, I've added the following after A.18.6(84/2):
AARM Discussion: In general, cursors are unordered. There is no
meaningful order between cursors that designate nodes in different containers.
It could make sense to talk about the order of two cursors that designate
nodes in the same ordered map, but the language does not do that. Since these
"<" and ">" operations work on any two nonnull cursors, they should be considered
a shorthand for a key comparison rather than providing some sort of cursor order.
AARM Reason: We do not provide "<=" or ">=" operations. Good taste in operator
definitions require that the usual properties hold for any A and B:
(A < B or} A = B) is the same as (A <= B)
(A > B or} A = B) is the same as (A >= B)
(A < B) is the same as (not (A >= B))
(A > B) is the same as (not (A <= B))
However, if A and B are equivalent but not equal keys, no matter how you define
"<=" and ">=", you cannot preserve all four of these relationships. In such cases,
we don't define all of the operators in order to avoid breaking this "good taste
in relational operators" principle.
I've added a similar version after A.18.9(103/2).
This discussion has been added to AI22-0005-1 (the AARM AI), and this topic will be closed.
****************************************************************
From: Stephen Baird
Sent: Tuesday, April 15, 2025 5:19 PM
AARM A.18(5.r) begins with
If a container's element type is controlled, ...
Should that be something like
If a container's element type has a controlled part, ...
?
And do we care?
If the element type is a one-field untagged record and that one field is of
a controlled type, then we still want this paragraph to apply, right?
****************************************************************
From: Randy Brukardt
Sent: Wednesday, April 16, 2025 2:03 PM
(1) John would complain about the possessive: "If the element type of the
container is controlled...". That was the first thing I saw.
(2) This is an AARM note, so completeness isn't critical...
(3)...but there is a space missing in "reusethe", so there's enough to fix
anyway. And I guess that you are right.
(4) We can do this in the AARM AI, so no ARG involvement needed.
****************************************************************
From: Randy Brukardt
Sent: Monday, May 18, 2026 9:37 PM
Github Issue #156 contains the following suggestions:
3.10.2(5): Each master, and each entity and view created by it, has an
accessibility level; when two levels are defined to be the same{ in a
particular construct by one of the following rules}, the accessibility
levels of the two associated entities are said to be tied to each other.
Accessibility levels are defined as follows:
{5.a Ramification: The relation thus defined on accessibility levels is an
explicitly symmetric and transitive form of the "defined to be the same"
relation. It is defined statically for the constituents of a particular
construct in the program and holds only in the context of this construct.}
21.b Ramification:{ Note the "considered" instead of "defined" to be the same.}
This rule only applies when the level of an explicitly aliased parameter of a
function is compared to that of the return object of the function. [...]
The normative wording change seems unnecessary with the suggested AARM note,
and the note should directly mention "tied":
{5.a Ramification: The tied relation thus defined on accessibility levels is an
explicitly symmetric and transitive relation. It is defined statically
for the constituents of a particular construct in the program and holds
only in the context of this construct.}
The other note also should mention "tied", and as it is the least important part
of this note, it should go at the end:
21.b Ramification:
This rule only applies when the level of an explicitly aliased parameter of
a function is compared to that of the return object of the function. If a
value designating the explicitly aliased parameter is created and stored
in a stand-alone object or passed as a parameter, this special property is
lost (even for the dynamic accessibility of anonymous access types in these
contexts).{ Note the "considered" instead of "defined" to be the same;
this rule does not cause "tied" accessibility levels.}
These changes were made to the draft RM.
****************************************************************
Editor's note (May 18, 2026): All of the items above this
marker have been included in the working version of the AARM.
****************************************************************