AI22-0022-1

!standard 3.9.4(34/2)                                      25-09-23  AI22-0022-1/10

!standard 3.9.4(35/2)

!standard 3.10(22/4)

!standard 4.3.5(93/5)

!standard 9.1(23)

!standard 9.5.2(33)

!standard 9.5.2(35)

!standard 9.5.2(37)

!standard 9.7.1(24)

!standard 12.3(25)

!standard A.18.33(3/3)

!class presentation 22-01-17

!status Revision-202Y  25-05-30

!status WG9 Approved 25-10-08

!status ARG Approved  14-0-0  25-05-28

!status work item 23-06-13

!status received 21-05-20

!assigned author Jeff Cousins

!priority Low

!difficulty Easy

!subject Difficult example issues from WG 9 review

!summary

Various examples are repaired.

!issue

(1) None of the types used in 9.1(26-7) or in 9.5.2(33, 35-7) are defined elsewhere in the Reference Manual. This violates the example principles as explained in 1.1.2(39.a.1/5). Should these examples be rewritten? (Yes.)

(2) Entry bodies are defined in 9.5.2, but the examples of 9.5.2 do not include any entry bodies. Should one be added? (Yes.)

(3) A.18.33(3/3) defines a Node_Maps vector. However, this package is not used anywhere in this example. Should it be used somewhere? (Yes.)

(4) The now-deleted example originally at 4.3.5(93-4/5) used an iterator on the container M, but the type of that container (Map_Type) does not have any iterator aspects, nor any definition of an iterator. This is an interesting example which it would be good to have in the Reference Manual; could it be replaced? (Yes.)

!recommendation

(See summary.)

!wording

Modify 3.9.4 (34/2):

Example{s} of a task interface:

Add after 3.9.4(35/2):

type Generic_Server is task interface;
procedure Shutdown (Object: Generic_Server) is abstract;

Add to 3.10 (22/4):

   type Server_Handle is

            not null access constant Generic_Server'Class; -- see 3.9.4

Append after 4.3.5 (93/5):

   package Birth_Year_Maps is new Ada.Containers.Indefinite_Ordered_Maps
     (Key_Type        => Integer,
      Element_Type => String);

   Birth_Year_Map : Birth_Year_Maps.Map :=
     [1998 => "Frederick",
      2004 => "William"];

   --  A vector made from the elements of a map:
   V := [for Elem of Birth_Year_Map => Elem];

   --  Is equivalent to:
   V := Empty_Vector (<estimate of size of Birth_Year_Map>);
   for Elem of Birth_Year_Map loop
       Append_One (V, Elem);
   end loop;

Precede 9.1 (23) with:

  type Work_Item is new Integer;

  type Keyboard_ID is new Integer;

  function New_Id return Keyboard_ID;

Replace 9.5.2(33) with:

entry Read(V : out Item);
entry Message (Level)(Text : String);  --  a family of entries, see 3.5.1
entry Shutdown;

Replace 9.5.2 (35) with:

accept Shutdown;

Replace 9.5.2 (37) with:

accept Message(Low) (Text : in String) do
   Log_Level:= Low;
   Log_Text.Replace_Element (Text);
end Message;

An example of an entry body can be found in the protected type example of 9.4.

Replace 9.7.1 (24) with:

task body Log_Server is
   package ACH renames Ada.Characters.Handling;
   package String_Holder is new Ada.Containers.Indefinite_Holders (String);

   Finished : Boolean:= False;
   Log_Text : String_Holder.Holder;
   Log_Level: Level;
   Log_Time : Ada.Calendar.Time;
   procedure Write_Entry (
      Time : Ada.Calendar.Time := Log_Time;
      Text : String            := Log_Text.Element;
      Alert: Level             := Log_Level) is ... 
begin
LOGGER:
   loop
      select
         accept Message(Low) (Text : in String) do
            Log_Level := Low;
            Log_Text.Replace_Element (Text);
         end Message;
      or
         accept Message(Medium) (Text : in String) do
            Log_Level := Medium;
            Log_Text.Replace_Element (Text);
         end Message;
      or
         accept Message(Urgent) (Text : in String) do
            Log_Level := Urgent;
            Log_Text.Replace_Element (ACH.To_Upper(Text));
         end Message;
      or
         accept Shutdown;
         Finished := True;
      end select;
           
      Log_Time := Ada.Calendar.Clock;
      exit LOGGER when Finished;
      Write_Entry;
   end loop LOGGER;
   Write_Entry (Alert => Low, Text => "Finished logging");
end Log_Server;

Add after 12.3 (25):

package Server_Task_Registration is new Ada.Containers.Indefinite_Vectors
   (Element_Type => Server_Handle, Index_Type => Positive);

Replace A.18.33 (10/3):

   Reached_From : array (Node) of Node;
   So_Far   : array (Node) of Distance := (others => Distance'Last);
   The_Path : Paths.List := Paths.Empty_List;
   Nearest_Distance : Distance;
   Next     : Node;
begin
   So_Far(Source)  := 0.0;

with:

   Reached_From : Node_Maps.Vector :=
      To_Vector (Ada.Containers.Count_Type (Node'Last - Node'First + 1));;
   So_Far   : array (Node) of Distance := (others => Distance'Last);
   The_Path : Paths.List := Paths.Empty_List;
   Nearest_Distance : Distance;
   Next     : Node;
begin
   So_Far(Source) := 0.0;

!discussion

(1) Type "Item" is used by many of these examples, so a consistent change might be helpful. In any case, all of these examples need to use types that are declared in other (or these) examples.

(2) An entry body example seems necessary. We refer to the one in 9.4(28). We could have put some examples here since we have accept statements (which is a fragment) here, an entry body would also be a fragment. But an example with a barrier doesn’t make a ton of sense only using local objects, the complete example of 9.4(28) is better.

(3) It makes the most sense to change Reached_From into a Node_Maps vector, with the necessary changes elsewhere. It was suggested to change Reached_From to the following:

  Reached_From : Node_Maps.Vector :=
       To_Vector (Ada.Containers.Count_Type (Node'Last - Node'First + 1));

 

(4) The example originally at 4.3.5(93/5) was deleted, as it was too difficult to fix it properly in the very limited time available. It would have been too confusing for Ada novices to understand why this example was OK, but they couldn't do the same with their programs without defining a lot of stuff.

It would be good to have a worked out iterator example somewhere (5.5.1 would be the obvious place), and if we had that we could use it here. Alternatively, we could give Iterator_Element and Default_Iterator aspects and a dummy iterator function specification for type Map_Type.

The original example was:

   --  A vector made from the elements of a map:
   V := [for Elem of M => Elem];

   --  Is equivalent to:
   V := Empty_Vector (<estimate of size of M>);
   for Elem of M loop
          Add_Positional (V, Elem);
   end loop;

 

But M is of Map_Type, which neither has an iterator subprogram nor any Iterator_Element or Default_Iterator aspects.

!ACATS test

No test is needed for examples.

!appendix

From: Niklas Holsti

WG 9 Review issue #153 - May 20, 2021

The types "Level" and "Item" are not defined here, making this example less than clear, especially because the syntax for entry declarations is given much later (in 9.5.2). There should be a comment "-- see 3.5.1 for Level". I haven't found where "Item" is defined; perhaps no specific "Item" type is intended; but "Item" is not so confusing because it occurs in a commonly seen context (formal parameter), while "Level" occurs in a context not seen before (index subtype for entry family).

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

From: Randy Brukardt

WG 9 Review issue #153 - May 21, 2021

I wonder if "Item" should be "Work_Item" (used earlier in this set of examples). The comment seems useful, Probably there should be one for some of the other things here (such as Work_Item). Jeff is the expert on these sorts of things (he's the one who checked all of the older examples for missing declaration errors); I've asked him.

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

From: Niklas Holsti

WG 9 Review issue #153 - May 21, 2021

The same remark applies to the examples in RM 9.5.2, for example paragraph 9.5.2(33).

Moreover, while RM 9.5.2 has examples of entry declarations and accept statements, it has no examples of entry bodies. Such examples would be nice to have, in particular for entry families.

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

From: Randy Brukardt

WG 9 Review issue #153 - May 21, 2021

Actually, none of the types or objects used in the example of 9.1 are defined elsewhere in the RM (with the single exception of Level, which probably is an accident). As such this entire set of examples violates the principles of RM examples set out in 1.1.2(39.a.1/5). It needs extensive revision, but it seems too late to do that at this time; given that there is nothing actually wrong

with the examples and they are not new text, I am marking this as a topic to be deferred.

That's also true with additional examples that are "nice to have", and connections between one bad example and another.

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

From: Niklas Holsti

WG 9 Review issue #166 - May 21, 2021

This example assumes that Map_Type has iterator aspects, which are not shown in its earlier declaration. Perhaps a comment should be added to this effect to avoid confusion.

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

From: Randy Brukardt

WG 9 Review issue #166 - May 25, 2021

Agreed. I'm tempted to delete 4.3.5(92/5) and 4.3.5(93/5), even though they are useful examples, because they violate our design principles for examples (in that they be compilable without "magic"). Defining the four needed aspects to support "of" iteration would really hide the purpose of these examples.

The only alternative I can think of would be to somehow depend on the A.18.33 example for these iterators - but I'm not sure how to do that.

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

From: Tucker Taft

WG 9 Review issue #166 - May 26, 2021

At this point I would suggest we do one of the following:

   * delete the two bullets; or

   * add a comment saying "-- This presumes the Map type has the necessary

         aspects to permit iteration -- see A.18.5 for an example of these aspects"; or

   * do nothing -- defer to next revision cycle.

I think I favor the last choice.

Interestingly, while looking at A.18.33, I discovered that the instance "Node_Maps" is not used, except in a "use" clause. This should be remedied some day as well, by changing "Reached_From" into a vector:

  Reached_From : Node_Maps.Vector :=

        To_Vector (Ada.Containers.Count_Type (Node'Last - Node'First + 1));

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

From: Randy Brukardt

WG 9 Review issue #166 - May 28, 2021

I prefer splitting the baby: deleting the two paragraphs now (in AI12-0430-1), but deferring this issue to revisit it in the future (perhaps we should create a proper container-like iterator example somewhere, maybe 5.5.2, and if we did that we could use it here). I think we should delete the paragraphs now because incorrect examples can cause major confusion, particularly in this

case when we're illustrating the use of iterators -- they really need to be properly declared so it doesn't appear that the compiler is conjuring them out of thin air.


 

From: Randy Brukardt

WG 9 Review issue #166 - May 28, 2021

Tucker's comment starting with "Interestingly" should also be deferred, since it is unclear whether there are any uses of Reached_From that expect being an array rather than a vector. (And it is an in an example that is not wrong and not modified, so it meets the standard reason for deferring - see #15.)


 

From: Editor, August 18, 2025

Niklas Holsti pointed out that the accept statement examples in 9.5.2(37) and 9.7.1(24) used a nonexistent construct, the “for Index in Level”. That syntax is only allowed in entry bodies, not in accept statements. (One could argue that if it is useful in entry bodies, it probably is useful in accept statements as well, as demonstrated by these examples, but it doesn’t exist today.)

The construct has been eliminated from the examples as Niklas’ Editorial Review of this AI.


 

From: Editor, August 19, 2025

The approved AI did not include any entry bodies in the examples of 9.5.2, as was requested by item (2) in the Issue. I’ve added a reference to the existing example in 9.4 to meet that request.


 

From: Editor, September 23, 2025

The original Editorial Review fixes here instantiated the non-existent Ada.Containers.Holders generic package. This has been corrected to use the intended Ada.Containers.Indefinite_Holders.