Minutes of ARG Meeting 63P

21, 22 July 2026

Attendees:

Tuesday Session:

Voting Members:

Steve Baird, Randy Brukardt, Jeff Cousins [arrives 12:03 EDT], Gary Dismukes, Christoph Grein, Niklas Holsti, Brad Moore [arrives 10:55 EDT], Jean-Pierre Rosen, Justin Squirek [arrives 11:04 EDT], Tucker Taft [leaves 13:04 EDT], Tullio Vardanega, Richard Wai.

Non-voting Members:

Bob Duff, Ed Fish.

Observers:

None.

Wednesday Session:

Voting Members:

Steve Baird, Randy Brukardt, Jeff Cousins [arrives 10:46 EDT], Gary Dismukes, Christoph Grein, Niklas Holsti , Brad Moore [arrives 10:39 EDT], Jean-Pierre Rosen, Tucker Taft, Tullio Vardanega, Richard Wai [arrives 13:02 EDT].

Non-voting Members:

Bob Duff.

Observers:

Jose Ruiz [leaves 12:58 EDT], Ethan Luis McDonough

Meeting Summary

The first session of the meeting convened on Tuesday, 21 July 2026 at 10:38 hours EDT and adjourned at 13:30 hours EDT. The second session of the meeting convened on Wednesday, 22 July 2026 at 10:36 hours EDT and adjourned at 13:32 hours EDT. The meeting was held using Zoom. The meeting covered many of the AIs on the agenda as well as several Github issues.

AI Summary

The following AIs were approved:
AI22-0167-1/02 T'Class'Image default behavior (9-0-0)
The following AIs were approved with editorial changes:
AI22-0161-2/03 Universal Unicode Text (6-0-4)
AI22-0168-1/03 Default-initialized constants (9-0-1)
The intentions of the following AIs were approved but they require a rewrite:
AI22-0147-4/01 Controlling what is a controlling parameter (9-0-1)
AI22-0148-1/06 Bounded and Unbounded Indefinite Objects (10-0-0)
AI22-0152-1/10 Optional objects (9-1-0)
AI22-0162-1/03 Storage Subpool Reclamation (11-0-0)
AI22-0165-1/02 Static rather dynamic language-defined checks (9-0-1)
AI22-0166-1/03 Subprogram aspect compatibility (9-0-2)
The following AIs were discussed and assigned to an editor:
AI22-0076-3/01 Static accessibility checking
AI22-0147-3/02 Controlling what is a controlling parameter
AI22-0163-1/02 Allowing 'Access to return a universal_access value
AI22-0164-2/02 Move and swap operations
The intention of the following AIs were voted, but then were discussed again later in the meeting (the final results are above):
AI22-0168-1/02 Default-initialized constants (11-0-1)
The following Github Issues were discussed and assigned to an editor to create an AI:
#57 Non-first subtypes for controlling parameters
#140 Entry index specifications for accept statements
The following Github Issues were discussed and assigned to an editor to close:
#69 Not null on array types

Detailed Minutes

Welcome

Steve welcomes everyone to this meeting.

Attendance

On Tuesday, Randy takes attendance. 9 voters, 2 non-voters, and 0 observers. (Three more voters showed up later; a voter left early.) On Wednesday, 8 voters, 1 non-voters, and 2 observers. (Three more voters showed up later, an observer left early.)

Apologies

Richard Wai said that he will be very late on Wednesday. Justin Squirek said he will be late on Tuesday and cannot attend at all on Wednesday. Alejandro Mosteo said he will miss both days. (both days), Tucker Taft has a conflicting medical appointment and will have to leave early on Tuesday. Last time, Jeff Cousins noted that he has a bowling match ("not tenpin") on Tuesday so he will be late.

Previous Meeting Minutes

There were no comments on the minutes: Approve minutes: 9-0-0.

Date and Venue of the Next Meeting

Our next electronic meeting is proposed for September 29-30th. Richard says that he will be in a plane to Hong Kong on those dates (or decompressing immediately afterwards). The next week is the AdaCore gathering, so no AdaCore employees could make that. We turn to the previous week. We try September 22-23rd. Tullio can't make the 23rd. We next try September 22, 24th. J-P can't do the 22nd. No alternatives seem to work (any earlier is too soon). We decide on September 22, 24th.

Changes to JTC1 Rules

Tullio notes that 3 years for a project is now a hard deadline, projects are canceled if not complete, and Working Groups can also be canceled if they have no projects. Randy notes that there are a lot of new rules, as ISO, IEC, and JTC1 rules have been merged to make a single unified set of rules taking effect in stages in the next year. Some of the changes may cause problems for us.

Unfinished Action Items

We don't discuss any of these items. Randy would like to remind Justin that he is at risk of losing his voting rights unless he completes his action item by the next meeting's deadline, but he isn't here. (He did mention it quickly when Justin later joined the meeting.)

Current Action Items

The combined unfinished old action items and new action items from the meeting are shown below.

Steve Baird:
Randy Brukardt:
    Editorial changes only:
Brad Moore:
Justin Squirek:
Tucker Taft:
Richard Wai:

Detailed Review

The minutes cover detailed review of Ada 2022 AIs (AI22s). The AI22s are presented in numeric order, which is not necessarily the order in which they were discussed. Votes are recorded as “for”-“against”-“abstentions”. For instance, a vote of 6-1-2 would have had six votes for, one vote against, and two abstentions.

If a paragraph number is identified as coming from the working Ada 202y AARM, the number refers to the text in draft 5 of the Ada 202y AARM. Paragraph numbers in other drafts may vary. Other paragraph numbers come from the final Ada 2022 AARM; again the paragraph numbers in the many drafts may vary.

Detailed Review of Ada 2022 AIs

AI22-0076-3/01 Static accessibility checking (Other AI versions)

Steve explains this version uses pragma Static_Checks, but was created before the terminology of that AI was settled.

The rules are not always associated with the places of the checks, but some of those are also need "known to succeed" rules.

More additional wording work is needed (in part to define "known to succeed" cases for existing dynamic checks). The AI goes back to Steve to add that wording.

Keep alive: 9-0-1. Christoph abstains.

AI22-0147-3/02 Controlling what is a controlling parameter (Other AI versions)

The syntax is "at". The idea is to turn off the systematic change of types during inheritance. There are many effects of this, which is why so much wording is affected.

Tucker mentions that AdaCore has internally looked at a feature like this, using attribute "Fixed".

Ed discusses whether this should be an aspect. That seems rather wordy.

Steve notes that this is just avoiding a nested package in the common case where all of the parameters are "at". Tucker says that AdaCore felt that was important. Not everyone agrees.

Steve notes that when overriding, you shouldn't be able to introduce an at where there wasn't one before. That would cause a lot of problems with dispatching and formal subprograms. Tucker says that this is covered in the proposed rules.

We don't have any restrictions on untagged types when overriding. We don't even require the modes to be the same, so there is no reason to make any restrictions on this feature.

Steve would like to look back at alternative 1. He doesn't buy this syntax.

Richard half-heartedly suggests putting the types in parens. Approximately no one likes that idea.

Most people are on board with the idea, but we have not determined an appropriate syntax.

Keep it alive: 9-1-2 Randy opposed (thinks it is too expensive to implement for a problem that doesn't occur very often, particularly if one limits packages to one abstraction), Justin, Gary abstain.

AI22-0147-4/01 Controlling what is a controlling parameter (Other AI versions)

Tucker explains this alternative, constructed overnight. It is essentially what AdaCore is currently pursuing. He made minimal changes to the wording, so some wordsmithing is required.

'Fixed (a new attribute) is a new kind of subtype which can only be used as parameters and results.

An alternative would be as an aspect of the parameter (and functions as a whole for the result). Randy notes that we have never looked at what that looks like.

Aspect name would be "Fixed". Several people suggest that could be confused with fixed point. Brad suggested "Pinned" (as no one would confuse that with fixed point or anything else in the language).

A question is raised about function results. The aspect would go on the function for that (as the return part itself doesn't have an aspect specification, and it would be ambiguous to add one).

"with Pinned" is agreed upon.

Jean-Pierre doesn't see the connection to derivation. Jean-Pierre suggests "Uncontrolling". Which does not make much sense for untagged types.

Brad suggests "with Tied". Steve thinks that has a binary feel.

The AdaCore people here are tasked with taking this recommendation back to the AdaCore working group to see their reaction.

Approve intent: 9-0-1 Randy abstains.

AI22-0148-1/06 Bounded and Unbounded Indefinite Objects (Other AI versions)

Tucker explains the changes. There are not many.

Randy asks about compatibility rules for parameter passing. For an unbounded in out parameter, is a constrained actual allowed? A bounded actual? A constrained-by-initial value actual? If so, that seems to complicate the implementation (we would need a runtime extent and some form of check). If not, where are the rules?

Tucker intended to cover that (see the recommendation), but there is no wording for that. That needs to be done before we can approve this.

Steve wonders about the cases of type conversions where you create (or don't) a new object. If you converted an object with a constrained extent to a type with an unbounded extent with a view conversion (or reference conversions), the original object would not have the appropriate data structures to support modification. That needs to be disallowed. We're unsure if other cases need to be disallowed (unbounded => constrained might cause issues if the constrained case has a different representation for some components). There shouldn't be a problem when a copy of the object is made, as then the representation can be adjusted as needed.

The properties of the designated subtype determine the extent of allocated objects. Since the model for all forms of these objects is based on storage pools, the rest of allocation is similar to creating a stand-alone object (just using the access type's pool rather than the scope's pool).

Mutable means "variable" in many other languages, so we don't want to be using the term formally. Bunch of ideas for an alternative term: "flexible", "changeable", "polymorphic", "plastic", "elastic". Tucker thinks that the term needs to reflect that the object can change shape. [Editor's note: Perhaps we should just say that and call them "shape-shifting" objects?]

Brad asks how this interacts with coextensions. We don't want to think about that now (some people say they don't want to think about that ever!).

Tucker will add wording to deal with the various issues identified. [Editor's note: The comments in the AI seem to show additional areas of wording that have not been handled, mostly identified in the May ARG meeting.]

Approve intent: 10-0-0.

AI22-0152-1/10 Optional objects (Other AI versions)

Tucker did a lot of work on this wording.

We discuss whether we need to get rid of the terms "null string" and "null range".

Bob says that he hates the term "null string". Steve agrees with Tucker is that it is confusing.

Randy has previously (and still does) object to the changing the terms "null string" and "null range" because they are widely used: not just in the RM, but also in error messages, documentation and books of all sorts, and probably in program comments. These are not going to change easily.

Randy also notes that the term "null constraint" is already very confusing (it doesn't have anything to do with null exclusions, but rather with composite types that have no discriminants.) It should be changed regardless of this AI.

Several people claim that they usually call null strings, "empty strings" in their code and writings.

Steve notes that "null range" doesn't have the confusion factor (there is no other interpretation). We could leave that one alone.

Straw vote: replace "null" blah with "empty" blah

In favor: 9; Oppose: 1 (Randy); Abstain: 3 (Ethan, Gary, Niklas)

Approve intent: 9-1-0. Niklas opposes. He thinks this is not enough for recursive data types, and overkill for optional components.

AI22-0161-2/03 Universal Unicode Text (Other AI versions)

Randy describes the changes and reasons. He added Nth as requested. He moved most of the Ada.Strings.Fixed operations to a child package Operations, in part to eliminate the dependence on Ada.Strings.Maps. He left the basic modification operations as they are available for type String (via built-ins like slice assignment), and we don't want Text to have less capability by default. (Also, only primitive operations can use prefix notation, and it seems important that all basic capabilities are available with prefix notation.)

He added the simplest possible Index function to the base package (without the converting map, which would add expense). The reason is that searching for a single character in type String is done by iterating the string and comparing characters. You could do that in UTF-8, but it is unnecessarily expensive as finding all of the character boundaries would be necessary (meaning reading the string extra times). A simple octet string comparison is cheaper and safe given the properties of UTF-8. So any searching should use Index which ought to use the faster approach. And searching for a delimiter (like a comma or semicolon) in an input string is a very common thing to do.

We generally agree on this these changes.

We look specifically "Add_Characters", "Subtract_Character". This seems to add characters rather than move a cursor. We look at other names "Advance" or "Advance_Cursor" is suggested. "Shifted_Cursor". We decide that a single routine is enough (as the Count can be negative). We discuss whether we should have a procedure version. We decide that we do want a procedure version, but we also need a function version (so, for instance, a function result or in parameter can be the source cursor). We leave that to Randy to add to this draft.

It is recommended to Randy to compile these specs before publishing them. He notes that he had syntax checked them, but that didn't catch that he had left out "raise" before Program_Error in all of the preconditions.

Approve AI with changes: 6-0-4. Steve, Christoph, Gary, Jean-Pierre all abstain.

We wonder why there are so many abstentions, wondering if there is a problem that needs to be addressed. Thus we take the unusual step of asking the members why they are abstaining. Steve and Gary say that they haven't studied the spec carefully enough to be confident it is what we need. Jean-Pierre says that he wants to give the specification more review before voting for it.

AI22-0162-1/03 Storage Subpool Reclamation (Other AI versions)

Randy tries to explain the problem as Brad isn't here. [Brad joins the meeting as Randy is doing that.]

We discuss the new requirement to call Finalize. It seems odd because of the ambiguity of "first". Steve asks whether a declaration of an integer makes a following call not "first". Brad notes that the reason for calling it first is that the objects inside of the subpools need to be finalized before the memory goes away.

Tucker would like a detailed explanation of how this works. A timeline of each step needed and who does it. Randy notes that we probably should have done that eons ago, as the model isn't a clear as it should be.

We look briefly at the wording for the main problem, and everyone agrees that it seems fine (changing from "finalize" to "reclaim"). Brad asks if the AI should be split into an obvious and non-obvious part. The issues are related enough that that doesn't seem like it would help much.

Brad and Randy will take this back, and try to describe a timeline of actions.

Approve intent: 11-0-0.

AI22-0163-1/02 Allowing 'Access to return a universal_access value (Other AI versions)

We discuss this, we need to modify the Legality Rules in 3.10.2 and 4.5.2 to make this work. We don't want to allow comparing two arbitrary access values with different designated types (or even an access-to-subprogram to an access-to-object). The current Legality Rules assume that 'Access has a designated type, and that anything that resolves to universal access is the literal null (so it is compatible with anything).

We note that just defining a "=" for the anonymous access type returned by Pool_of_Subpool would fix the actual problem. The rules for the predefined "=" are designed so that will work (otherwise, visibility issues would break that).

Is this sufficiently worthwhile to do the work? In particular, will this happen to others? Perhaps, but they could also use the workaround defining an "=".

We make no conclusion on that point, and return the AI to Brad to figure out what to do.

Keep alive: 11-0-0.

AI22-0164-2/02 Move and swap operations (Other AI versions)

Tucker explains the reason for these operations.

If two items are in the same storage area, then you are guaranteed a move. (Along with limited components.)

Niklas would like Move on objects that have parts that are movable to move those parts with the rest copied. He thinks that one sets any non-optional components to the default value after such a Move.

Steve thinks a similar thing, giving (repeatedly) the example of a non-optional array containing optional components.

Tucker thinks that the source should be null afterwards, and that requires the source to be an optional object.

Bob notes that null is not tied to pointers anymore. He thinks that all parts should be null afterward.

Richard (musing out loud) wonders why Move isn't the default, but then he realizes that Move is destructive on the source.

Bob would like to call these things Move and Swap and have them be some form of attributes. Tucker notes that Swap is symmetric, which doesn't fit an attribute well. Randy notes that the attributes could have a subtype prefix, in which case the symmetry problem goes away. Tucker notes that Move is not symmetric, perhaps the answer is different for it. People previously were uncomfortable with the prefix of an attribute being modified, and it is unlikely that has gone away.

Jean-Pierre suggested using a generic. Tucker says that makes the syntax extensive. You would end up with a lot of instantations. Randy notes that we all do that with Unchecked_Conversion, and it doesn't matter (they're all equivalent and built-in anyway, the same would be true here). Tucker notes that Unchecked_Conversion and Unchecked_Deallocation are known to be unsafe and we want to limit the use of them. [Editor's note: This seems to be a weak argument; Move is noticably less safe than := (since it destroys the source, and if there are any aliased accesses to the source [such as passed parameters], can introduce erroneous execution). One can make an argument that Move should be limited to circumstances where nothing else will work.]

We go back to the question of moving internal parts. Tucker thinks that the result should be null, because the source is no longer is usable.

The idea of clobbering parts of a private type without the knowledge of the package that defines that private type is essentially privacy breaking. That sounds horrible. It doesn't matter what the parts are set to, the package may be depending upon a relationship between them and other components/discriminants.

Tucker notes that Move is about moving the ownership of a part of an object from one object to another.

Swap and Move probably should be separate, since the requirements are different.

The discussion ends as we have reached the end of the meeting, with very little in the way of conclusions.

Keep alive: 10-0-1 Christoph abstains.

AI22-0165-1/02 Static rather dynamic language-defined checks (Other AI versions)

Randy explains the various ideas.

There are three checking states: Suppressed/Static_Checking/normal (unsuppressed dynamic checks).

We want a pragma Dynamic_Checks, using Unsuppress to cancel Static_Checking is considered too weird. Randy thinks that it will be essentially equivalent to Unsuppress (as it will restore the normal state). Exactly how that will be described is still to be determined.

The "known to succeed" cases defined here are just trying to show examples. Most likely, there will be a bunch of terms that effectively define a simple flow analysis, and then some rules for specific checks to take advantage of that analysis. The rules Randy suggests are very conservative. The idea is that a simple if expression can be used to make a check succeed in its dependent expression(s), and that a simple if statement can be used to make a check succeed in the first dependent statement (which can be a block defining a constrained constant that can make other checks succeed). We don't need to go further than that (even though a compiler is likely to go much further).

Jeff wonders if we intend to include discriminant checks. Yes, those are one of the checks that should have some "known to succeed" rules. Randy mostly concentrated on Access_Check because validity issues don't come into play (there are no uninitialized access values) simplifying the rules, and because he has already written such an analyzer in Janus/Ada so he had an idea of the issues involved.

Bob asks if the compiler can be less smart than the language rules (as in regular static checks versus strict static checks). No, there is a permission to find other checks that are known to succeed, there's no permission to disallow the ones already defined that way. One hopes that compilers take advantage of checks that are defined to be known to succeed by not generating any code for such checks (of course, the Standard can't say much about that, Implementation Advice is possible).

Tucker notes that we could put these rules "known to succeed" (and even the pragmas??) into Annex H if they are considered too complex for the core. The main users worried about avoiding checks are those in Safety Critical environments that are trying to avoid raising exceptions.

Steve prefers one Static_Checks pragma. A couple of others concur. Randy notes that we have to be careful about the obsolescent second parameter to checking pragmas, we probably want to allow implementations to add one here as well if they want (Unsuppress/Dynamic_Checks already has one).

The default for Strict should be False, it is highly likely that compilers will find many additional checks that are known to succeed that would be too hard to define in the RM. Jean-Pierre argues for True, he thinks Ada should be portable by default. The group sways between these thoughts without any conclusion. Someone notes that if there are two pragmas, then we don't have to decide a default.

So we decide to stay with two pragmas, at least for now.

This goes back to Randy to finish the wording as directed.

Approve intent: 9-0-1. Christoph abstains.

AI22-0166-1/03 Subprogram aspect compatibility (Other AI versions)

Steve explains the issue. There are a number of aspects that don't need to exactly match, but there are constraints that need to be followed.

In particular, there are number of rules that need to be enforced on each aspect, and there are a number of aspects that need these rules. This is an N*M problem. By giving this a term, we turn this into one rule for all aspects in each place a rule is needed, and one definition per aspect that needs the rules specified, making this an N+M problem.

In this case, N (the number of aspects) is 6 (and there are likely to be more in the future), and the number of rules (M) is 4.

The AI deletes all of the old specific rules; based on the number of deletions, we only had about 10 of the needed 24 rules (which should explain the need for this AI).

Ed asks if the default compatibility needs a name; he suggests "implicitive". Steve notes that it is a default, so it doesn't need a name. It would be more obvious if we did use a term, then anyone that needs to figure out the rule, they can look up the term. After some wonderment, we determine that "implicitive" is actually a real word, so we settle on "implicitive call-specializing aspect". Steve notes this adds just a single word to the proposed wording.

Approve intent: 9-0-2. Gary, Richard abstain.

AI22-0167-1/02 T'Class'Image default behavior (Other AI versions)

Steve explains this wording.

There is no discussion.

Approve AI: 9-0-0.

AI22-0168-1/02 Default-initialized constants (Other AI versions)

Randy explains the idea.

We discuss the use. Randy notes that he has declared variables in order to initialize constants. Tucker says he has as well.

The syntax is weird, move := to the main items.

Tucker wonders if we need to have this for components. Steve notes that it is exactly the same as saying nothing in the case of components, and having two ways to do the same thing. Randy notes that saying <> is intentionally default initialized, and saying nothing is "don't care". Jean-Pierre says that a style tool could enforce that all objects (including components) are intentionally initialized (somehow).

Randy notes that the syntax default_expression is shared for default parameters, which adds an additional challenge. Someone notes that one can always use a declare expression if they absolutely want to do this; it's wordier than we might like but always possible. We decide to forget this, it can be handled later if there is demand.

The redundant text in 3.3.1(10) is considered confusing. There is a suggestion to change Initial_Value to Initial_Specification as <> doesn't itself have a value.

We close the discussion as it is devolving into wordsmithing. The AI will go back to Randy for rewording.

Approve intent: 11-0-1 Gary abstained.

AI22-0168-1/03 Default-initialized constants (Other AI versions)

Randy explains the changes made overnight. These were mostly the wording changes requested. He also beefed up the example and added a bit of discussion about setting discriminant values other than the defaults.

We do some wordsmithing.

Approve AI with changes: 9-0-1. Gary abstains.

Detailed Review of Ada Github Issues

#57 – Non-first subtypes for controlling parameters

The suggestion from Tucker is to use the class-wide predicates version, making them nonoverridable. So Randy will dust off the old AI12-0243-2.

#69 – Not null on array types

A dynamic predicate would have the same effect.

The original poster was trying to get the checks made at compile-time, but no one can understand how this feature would help that.

Someone mentions that this question has a common form of "I know that Ada has a way to do X, but I don't want to use it because of Y, so I want a new feature." That is a very weak argument; new features have to pass a higher bar simply because of the overhead that they add to understanding the language as well as the implementation costs.

The Editor should reply that the ARG looked at it and determined that there is insufficient interest in this proposal. He should be pointed at the proposed new feature to prevent dynamic checks (in AI22-0165-1). And then close the issue.

#140 – Entry index specifications for accept statements

Richard Wai says that he uses plenty of accept statements, and he has tried to do this and had to pivot to other approaches.

Someone asks why this couldn't have been a parameter instead. Randy notes that there could be a separate "critical" choice which gets priority, while the rest of the actions share code. It is always annoying to have to repeat code just because of some language rule.

The compiler could macro-expand the choices (one per value) rather than changing the underlying model. However, that would require the bounds on the entry index to be static. That wouldn't be the worst restriction.

Niklas notes that one can use a range for protected entries, so it seems weird to not be able to do so for accept statements.

Steve wonders if this would have a new case for entries. It would be an accept statement that could take from multiple queues. But as noted above, it would be equivalent to a select statement with all of the choices manually expanded, so it seems that the implementation already has to be able to do something similar.

Richard volunteers to write this up. He might be able to prototype this is in GNAT.