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

!summary

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.

!issue

!response

!appendix

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.

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