# Version 1.6 of ais/ai-00433.txt

Unformatted version of ais/ai-00433.txt version 1.6
Other versions for file ais/ai-00433.txt

!standard 1.1.4(9)          05-09-20 AI95-00433/05
!standard 2.3(8)
!standard 2.5(5)
!standard 2.6(9)
!standard 2.8(29)
!standard 3.2.2(15)
!standard 3.3.1(27)
!standard 3.3.1(29)
!standard 3.3.1(31)
!standard 3.3.1(33)
!standard 3.3.2(10)
!standard 3.6(30)
!standard 3.7(37)
!standard 3.9.4(1)
!standard 3.10(22)
!standard 3.10.1(19)
!standard 3.10.1(20)
!standard 3.10.1(21)
!standard 4.3.3(43)
!standard 4.4(15)
!standard 6.5.1(1)
!standard 6.7(1)
!standard 8.3.1(1)
!standard 9.1(24)
!standard 9.11(3)
!standard 9.11(6)
!standard 9.11(7)
!standard 9.11(8)
!standard 9.11(9)
!standard 9.11(10)
!standard 10.1.2(8)
!standard 11.3(6)
!standard 11.4.3(2)
!standard 11.4.3(6)
!standard 12.5.5(5)
!standard 12.6(18)
!standard 12.7(11)
!class amendment 05-05-18
!status Amendment 200Y 05-05-18
!status ARG Approved 12-0-0 05-06-19
!status work item 05-05-18
!priority High
!difficulty Easy
!subject Examples in the Standard
!summary
(See proposal.)
!problem
The examples in the RM must be updated to reflect the new language.
!proposal
Tuck did the examples in a stream-of-consciousness manner, and Pascal got the short stick to write an AI.
!wording
(See corrigendum.)
!discussion
The example of AI-407 depends on the example of 3.9.4 given here.
!example
An example for examples? Get real!
!corrigendum 1.1.4(9)
Replace the paragraph:
return_statement
::= return [expression];
return_statement ::= return; | return expression;
by:
simple_return_statement
::= return [expression];
simple_return_statement ::= return; | return expression;
!corrigendum 2.3(8)
Replace the paragraph:
Count X Get_Symbol Ethelyn Marion
Snobol_4 X1 Page_Count Store_Next_Item
by:
Count X Get_Symbol Ethelyn Marion Snobol_4 X1 Page_Count Store_Next_Item Πλάτων -- Plato Чайковский -- Tchaikovsky θ φ -- Angles
!corrigendum 2.5(5)
Replace the paragraph:
'A' '*' ''' ' '
by:
'A' '*' ''' ' ' 'L' 'Л' 'Λ' -- Various els. '∞' 'א' -- Big numbers - infinity and aleph.
!corrigendum 2.6(9)
Replace the paragraph:
"Message of the day:"
"" -- a null string literal " " "A" """" -- three string literals of length 1
"Characters such as \$, %, and } are allowed in string literals"
by:
"Message of the day:"
"" -- a null string literal " " "A" """" -- three string literals of length 1
"Characters such as \$, %, and } are allowed in string literals" "Archimedes said ""Εύρηκα""" "Volume of cylinder (πr²h) = "
!corrigendum 2.8(29)
Replace the paragraph:
pragma List(Off); -- turn off listing generation pragma Optimize(Off); -- turn off optional optimizations pragma Inline(Set_Mask); -- generate code for Set_Mask inline pragma Suppress(Range_Check, On => Index); -- turn off range checking on Index
by:
pragma List(Off); -- turn off listing generation pragma Optimize(Off); -- turn off optional optimizations pragma Inline(Set_Mask); -- generate code for Set_Mask inline pragma Import(C, Put_Char, External_Name => "putchar"); -- import C putchar function
!corrigendum 3.2.2(15)
Replace the paragraph:
subtype Rainbow is Color range Red .. Blue; -- see 3.2.1 subtype Red_Blue is Rainbow; subtype Int is Integer; subtype Small_Int is Integer range -10 .. 10; subtype Up_To_K is Column range 1 .. K; -- see 3.2.1 subtype Square is Matrix(1 .. 10, 1 .. 10); -- see 3.6 subtype Male is Person(Sex => M); -- see 3.10.1
by:
subtype Rainbow is Color range Red .. Blue; -- see 3.2.1 subtype Red_Blue is Rainbow; subtype Int is Integer; subtype Small_Int is Integer range -10 .. 10; subtype Up_To_K is Column range 1 .. K; -- see 3.2.1 subtype Square is Matrix(1 .. 10, 1 .. 10); -- see 3.6 subtype Male is Person(Sex => M); -- see 3.10.1 subtype Binop_Ref is not null Binop_Ptr; -- see 3.10
!corrigendum 3.3.1(27)
Replace the paragraph:
John, Paul : Person_Name := new Person(Sex => M); -- see 3.10.1
by:
John, Paul : not null Person_Name := new Person(Sex => M); -- see 3.10.1
!corrigendum 3.3.1(29)
Replace the paragraph:
John : Person_Name := new Person(Sex => M); Paul : Person_Name := new Person(Sex => M);
by:
John : not null Person_Name := new Person(Sex => M); Paul : not null Person_Name := new Person(Sex => M);
!corrigendum 3.3.1(31)
Replace the paragraph:
Count, Sum : Integer; Size : Integer range 0 .. 10_000 := 0; Sorted : Boolean := False; Color_Table : array(1 .. Max) of Color; Option : Bit_Vector(1 .. 10) := (others => True); Hello : constant String := "Hi, world.";
by:
Count, Sum : Integer; Size : Integer range 0 .. 10_000 := 0; Sorted : Boolean := False; Color_Table : array(1 .. Max) of Color; Option : Bit_Vector(1 .. 10) := (others => True); Hello : aliased String := "Hi, world."; θ, φ : Float range -π .. +π;
!corrigendum 3.3.1(33)
Replace the paragraph:
Limit : constant Integer := 10_000; Low_Limit : constant Integer := Limit/10; Tolerance : constant Real := Dispersion(1.15);
by:
Limit : constant Integer := 10_000; Low_Limit : constant Integer := Limit/10; Tolerance : constant Real := Dispersion(1.15); Hello_Msg : constant access String := Hello'Access; -- see 3.10.2
!corrigendum 3.3.2(10)
!comment This is just a correction to an existing example.
@drepl @xcode<Max : @b<constant> := 500; --@ft<@i< an integer number>> Max_Line_Size : @b<constant> := Max/6 --@ft<@i< the integer 83>> Power_16 : @b<constant> := 2**16; --@ft<@i< the integer 65_536>> One, Un, Eins : @b<constant> := 1; --@ft<@i< three different names for 1>>> @dby @xcode<Max : @b<constant> := 500; --@ft<@i< an integer number>> Max_Line_Size : @b<constant> := Max/6; --@ft<@i< the integer 83>> Power_16 : @b<constant> := 2**16; --@ft<@i< the integer 65_536>> One, Un, Eins : @b<constant> := 1; --@ft<@i< three different names for 1>>>
!corrigendum 3.6(30)
Replace the paragraph:
Grid : array(1 .. 80, 1 .. 100) of Boolean; Mix : array(Color range Red .. Green) of Boolean; Page : array(Positive range <>) of Line := -- an array of arrays (1 | 50 => Line'(1 | Line'Last => '+', others => '-'), -- see 4.3.3 2 .. 49 => Line'(1 | Line'Last => '|', others => ' ')); -- Page is constrained by its initial value to (1..50)
by:
Grid : array(1 .. 80, 1 .. 100) of Boolean; Mix : array(Color range Red .. Green) of Boolean; Msg_Table : constant array(Error_Code) of access constant String := (Too_Big => new String'("Result too big"), Too_Small => ...); Page : array(Positive range <>) of Line := -- an array of arrays (1 | 50 => Line'(1 | Line'Last => '+', others => '-'), -- see 4.3.3 2 .. 49 => Line'(1 | Line'Last => '|', others => ' ')); -- Page is constrained by its initial value to (1..50)
!corrigendum 3.7(37)
Replace the paragraph:
type Item(Number : Positive) is record Content : Integer; -- no component depends on the discriminant end record;
by:
task type Worker(Prio : System.Priority; Buf : access Buffer) is -- discriminants used to parameterize the task type (see 9.1) pragma Priority(Prio); -- see D.1 entry Fill; entry Drain; end Worker;
!corrigendum 3.9.4(1)
!comment This is not the full section, see the conflict files for that.
@dinsa Nonlimited interface types have predefined nonabstract equality operators. These may be overridden with user-defined abstract equality operators. Such operators will then require an explicit overriding for any nonabstract descendant of the interface.
@dinss @i<@s8<Examples>>
@i<Example of a limited interface and a synchronized interface extending it:>
@xcode<@b<type> Queue @b<is limited interface>; @b<procedure> Append(Q : @b<in out> Queue; Person : @b<in> Person_Name) @b<is abstract>; @b<procedure> Remove_First(Q : @b<in out> Queue;
Person : @b<out> Person_Name) @b<is abstract>;
@b<function> Cur_Count(Q : @b<in> Queue) @b<return> Natural @b<is abstract>; @b<function> Max_Count(Q : @b<in> Queue) @b<return> Natural @b<is abstract>; -- @ft<@i<See 3.10.1 for Person_Name.>>
Queue_Error : @b<exception>; --@ft<@i< Append raises Queue_Error if Count(Q) = Max_Count(Q)>> --@ft<@i< Remove_First raises Queue_Error if Count(Q) = 0>>
@b<type> Synchronized_Queue @b<is synchronized interface and> Queue; --@ft<@i< see 9.11>> @b<procedure> Append_Wait(Q : @b<in out> Synchronized_Queue;
Person : @b<in> Person_Name) @b<is abstract>;
@b<procedure> Remove_First_Wait(Q : @b<in out> Synchronized_Queue;
Person : @b<out> Person_Name) @b<is abstract>;
...
@b<procedure> Transfer(From : @b<in out> Queue'Class;
To : @b<in out> Queue'Class; Number : @b<in> Natural := 1) @b<is>
Person : Person_Name;
@b<begin>
@b<for> I @b<in> 1..Number @b<loop>
Remove_First(From, Person); Append(To, Person);
@b<end loop>;
@b<end> Transfer;>
This defines a Queue interface defining a queue of people. (A similar design could be created to define any kind of queue simply by replacing Person_Name by an appropriate type.) The Queue interface has four dispatching operations, Append, Remove_First, Cur_Count, and Max_Count. The body of a class-wide operation, Transfer is also shown. Every non-abstract extension of Queue must provide implementations for at least its four dispatching operations, as they are abstract. Any object of a type derived from Queue may be passed to Transfer as either the From or the To operand. The two operands need not be of the same type in any given call.
The Synchronized_Queue interface inherits the four dispatching operations from Queue and adds two additional dispatching operations, which wait if necessary rather than raising the Queue_Error exception. This synchronized interface may only be implemented by a task or protected type, and as such ensures safe concurrent access.
@i<Example use of the interface:>
@xcode<@b<type> Fast_Food_Queue @b<is new> Queue @b<with record> ...; @b<procedure> Append(Q : @b<in out> Fast_Food_Queue; Person : @b<in> Person_Name); @b<procedure> Remove_First(Q : @b<in out> Fast_Food_Queue; Person : @b<in> Person_Name); @b<function> Cur_Count(Q : @b<in> Fast_Food_Queue) @b<return> Natural; @b<function> Max_Count(Q : @b<in> Fast_Food_Queue) @b<return> Natural;
...
Cashier, Counter : Fast_Food_Queue;
... -- @ft<@i<Add George (see 3.10.1) to the cashier's queue:>> Append (Cashier, George); -- @ft<@i<After payment, move George to the sandwich counter queue:>> Transfer (Cashier, Counter); ...>
An interface such as Queue can be used directly as the parent of a new type (as shown here), or can be used as a progenitor when a type is derived. In either case, the primitive operations of the interface are inherited. For Queue, the implementation of the four inherited routines must be provided. Inside the call of Transfer, calls will dispatch to the implementations of Append and Remove_First for type Fast_Food_Queue.
@xcode<@b<type> Serial_Device @b<is task interface>; --@ft<@i< see 9.1>> @b<procedure> Read (Dev : @b<in> Serial_Device; C : @b<out> Character) @b<is abstract>; @b<procedure> Write(Dev : @b<in> Serial_Device; C : @b<in> Character) @b<is abstract>;>
The Serial_Device interface has two dispatching operations which are intended to be implemented by task entries (see 9.1).
!corrigendum 3.10(22)
Replace the paragraph:
type Peripheral_Ref is access Peripheral; -- see 3.8.1 type Binop_Ptr is access all Binary_Operation'Class; -- general access-to-class-wide, see 3.9.1
by:
type Peripheral_Ref is not null access Peripheral; -- see 3.8.1 type Binop_Ptr is access all Binary_Operation'Class; -- general access-to-class-wide, see 3.9.1
!corrigendum 3.10.1(19)
Replace the paragraph:
type Person(<>); -- incomplete type declaration type Car; -- incomplete type declaration
by:
type Person(<>); -- incomplete type declaration type Car is tagged; -- incomplete type declaration
!corrigendum 3.10.1(20)
Replace the paragraph:
type Person_Name is access Person; type Car_Name is access all Car;
by:
type Person_Name is access Person; type Car_Name is access all Car'Class;
!corrigendum 3.10.1(21)
Replace the paragraph:
type Car is record Number : Integer; Owner : Person_Name; end record;
by:
type Car is tagged record Number : Integer; Owner : Person_Name; end record;
!corrigendum 4.3.3(43)
Insert after the paragraph:
D : Bit_Vector(M .. N) := (M .. N => True); -- see 3.6 E : Bit_Vector(M .. N) := (others => True); F : String(1 .. 1) := (1 => 'F'); -- a one component aggregate: same as "F"
the new paragraphs:
Example of an array aggregate with defaulted others choice and with an applicable index constraint provided by an enclosing record aggregate:
Buffer'(Size => 50, Pos => 1, Value => String'('x', others => <>)) -- see 3.7
!corrigendum 4.4(15)
Replace the paragraph:
Volume -- primary not Destroyed -- factor 2*Line_Count -- term -4.0 -- simple expression -4.0 + A -- simple expression B**2 - 4.0*A*C -- simple expression Password(1 .. 3) = "Bwv" -- relation Count in Small_Int -- relation Count not in Small_Int -- relation Index = 0 or Item_Hit -- expression (Cold and Sunny) or Warm -- expression (parentheses are required) A**(B**C) -- expression (parentheses are required)
by:
Volume -- primary not Destroyed -- factor 2*Line_Count -- term -4.0 -- simple expression -4.0 + A -- simple expression B**2 - 4.0*A*C -- simple expression R*Sin(θ)*Cos(φ) -- simple expression Password(1 .. 3) = "Bwv" -- relation Count in Small_Int -- relation Count not in Small_Int -- relation Index = 0 or Item_Hit -- expression (Cold and Sunny) or Warm -- expression (parentheses are required) A**(B**C) -- expression (parentheses are required)
!corrigendum 6.5.1(1)
!Comment This is a new clause, so this a dummy and the real thing is in the
!comment conflicts.
@dinsa If the body of a non-returning procedure completes normally, Program_Error is raised at the point of the call.
@dinss @i<@s8<Examples>>
@xcode<@b<procedure> Fail(Msg : String); --@ft<@i< raises Fatal_Error exception>> @b<pragma> No_Return(Fail);
--@ft<@i< Inform compiler and reader that procedure never returns normally>>>
!corrigendum 6.7(1)
!Comment This is a new clause, so this a dummy and the real thing is in the
!comment conflicts.
@dinsa The execution of a null procedure is invoked by a subprogram call. For the execution of a subprogram call on a null procedure, the execution of the @fa<subprogram_body> has no effect.
@dinst @i<@s8<Examples>>
@xcode<@b<procedure> Simplify(Expr : @b<in out> Expression) @b<is null>; --@ft<@i< see 3.9>> --@ft<@i< By default, Simplify does nothing, but it may be overridden in extensions of Expression>>>
!corrigendum 8.3.1(1)
!Comment This is a new clause, so this a dummy and the real thing is in the
!comment conflicts.
@dinsa Indicator! @dinst @i<@s8<Examples>>
The use of @fa<overriding_indicator>s allows the detection of errors at compile-time that otherwise might not be detected at all. For instance, we might declare a security queue derived from the Queue interface of 3.9.4 as:
@xcode<@b<type> Security_Queue @b<is new> Queue @b<with record> ...;>
@xcode<@b<overriding> @b<procedure> Append(Q : @b<in out> Security_Queue; Person : @b<in> Person_Name);>
@xcode<@b<overriding> @b<procedure> Remove_First(Q : @b<in out> Security_Queue; Person : @b<in> Person_Name);>
@xcode<@b<overriding> @b<function> Cur_Count(Q : @b<in> Security_Queue) @b<return> Natural;>
@xcode<@b<overriding> @b<function> Max_Count(Q : @b<in> Security_Queue) @b<return> Natural;>
@xcode<@b<not overriding> @b<procedure> Arrest(Q : @b<in out> Security_Queue; Person : @b<in> Person_Name);>
The first four subprogram declarations guarantee that these subprograms will override the four subprograms inherited from the Queue interface. A misspelling in one of these subprograms will be detected by the implementation. Conversely, the declaration of Arrest guarantees that this is a new operation.
!corrigendum 9.1(24)
Replace the paragraph:
task type Keyboard_Driver(ID : Keyboard_ID := New_ID) is entry Read (C : out Character); entry Write(C : in Character); end Keyboard_Driver;
by:
task type Keyboard_Driver(ID : Keyboard_ID := New_ID) is new Serial_Device with -- see 3.9.4 entry Read (C : out Character); entry Write(C : in Character); end Keyboard_Driver;
!corrigendum 9.11(3)
Replace the paragraph:
task body Producer is Char : Character; begin loop ... -- produce the next character Char Buffer.Write(Char); exit when Char = ASCII.EOT; end loop; end Producer;
by:
task body Producer is Person : Person_Name; -- see 3.10.1 begin loop ... -- simulate arrival of the next customer Buffer.Append_Wait(Person); exit when Person = null; end loop; end Producer;
!corrigendum 9.11(6)
Replace the paragraph:
task body Consumer is Char : Character; begin loop Buffer.Read(Char); exit when Char = ASCII.EOT; ... -- consume the character Char end loop; end Consumer;
by:
task body Consumer is Person : Person_Name; begin loop Buffer.Remove_First_Wait(Person); exit when Person = null; ... -- simulate serving a customer end loop; end Consumer;
!corrigendum 9.11(7)
Replace the paragraph:
The buffer object contains an internal pool of characters managed in a round-robin fashion. The pool has two indices, an In_Index denoting the space for the next input character and an Out_Index denoting the space for the next output character.
by:
The buffer object contains an internal array of person names managed in a round-robin fashion. The array has two indices, an In_Index denoting the index for the next input person name and an Out_Index denoting the index for the next output person name.
The Buffer is defined as an extension of the Synchronized_Queue interface (see 3.9.4), and as such promises to implement the abstraction defined by that interface. By doing so, the Buffer can be passed to the Transfer class-wide operation defined for objects of a type covered by Queue'Class.
!corrigendum 9.11(8)
Replace the paragraph:
protected Buffer is entry Read (C : out Character); entry Write(C : in Character); private Pool : String(1 .. 100); Count : Natural := 0; In_Index, Out_Index : Positive := 1; end Buffer;
by:
protected Buffer is new Synchronized_Queue with -- see 3.9.4 entry Append_Wait(Person : in Person_Name); entry Remove_First_Wait(Person : out Person_Name); function Cur_Count return Natural; function Max_Count return Natural; procedure Append(Person : in Person_Name); procedure Remove_First(Person : out Person_Name); private Pool : Person_Name_Array(1 .. 100); Count : Natural := 0; In_Index, Out_Index : Positive := 1; end Buffer;
!corrigendum 9.11(9)
Replace the paragraph:
protected body Buffer is entry Write(C : in Character) when Count < Pool'Length is begin Pool(In_Index) := C; In_Index := (In_Index mod Pool'Length) + 1; Count := Count + 1; end Write;
by:
protected body Buffer is entry Append_Wait(Person : in Person_Name) when Count < Pool'Length is begin Append(Person); end Append_Wait;
procedure Append(Person : in Person_Name) is begin if Count = Pool'Length then raise Queue_Error with "Buffer Full"; -- see 11.3 end if; Pool(In_Index) := Person; In_Index := (In_Index mod Pool'Length) + 1; Count := Count + 1; end Append;
!corrigendum 9.11(10)
Replace the paragraph:
entry Read(C : out Character) when Count > 0 is begin C := Pool(Out_Index); Out_Index := (Out_Index mod Pool'Length) + 1; Count := Count - 1; end Read; end Buffer;
by:
entry Remove_First_Wait(Person : out Person_Name) when Count > 0 is begin Remove_First(Person); end Remove_First_Wait;
procedure Remove_First(Person : out Person_Name) is begin if Count = 0 then raise Queue_Error with "Buffer Empty"; -- see 11.3 end if; Person := Pool(Out_Index); Out_Index := (Out_Index mod Pool'Length) + 1; Count := Count - 1; end Remove_First;
function Cur_Count return Natural is begin return Buffer.Count; end Cur_Count;
function Max_Count return Natural is begin return Pool'Length; end Max_Count; end Buffer;
!corrigendum 10.1.2(8)
!comment There is a lot of text inserted here, so this a dummy and the real
!comment thing is in the conflicts.
@dinsa @xbullet<in the scope of a @fa<use_clause> which names an entity declared within the declarative region of the @fa<library_item>.>
@dinss @i<@s8<Examples>>
@xcode<@b<package> Office @b<is> @b<end> Office;>
@b<end> Office.Locations;>
@xcode<@b<limited with> Office.Departments; --@ft<@i< types are incomplete>> @b<private with> Office.Locations; --@ft<@i< only visible in private part>> @b<package> Office.Employees @b<is>
@b<type> Employee @b<is private>;
@b<function> Dept_Of(Emp : Employee) @b<return access> Departments.Department; @b<procedure> Assign_Dept(Emp : @b<in out> Employee;
Dept : @b<access> Departments.Department);
...
@b<private>
@b<type> Employee @b<is>
@b<record>
Dept : @b<access> Departments.Department; Loc : Locations.Location; ...
@b<end record>;
@b<end> Office.Employees;
@b<limited with> Office.Employees; @b<package> Office.Departments @b<is>
@b<type> Department @b<is private>;
@b<function> Manager_Of(Dept : Department) @b<return access> Employees.Employee; @b<procedure> Assign_Manager(Dept : @b<in out> Department;
Mgr : @b<access> Employees.Employee);
...
@b<end> Office.Departments;>
The @fa<limited_with_clause> may be used to support mutually dependent abstractions that are split across multiple packages. In this case, an employee is assigned to a department, and a department has a manager who is an employee. If a @fa<with_clause> with the reserved word @b<private> appears on one library unit and mentions a second library unit, it provides visibility to the second library unit, but restricts that visibility to the private part and body of the first unit. The compiler checks that no use is made of the second unit in the visible part of the first unit.
!corrigendum 11.3(6)
Replace the paragraph:
by:
raise Ada.IO_Exceptions.Name_Error; -- see A.13 raise Queue_Error with "Buffer Full"; -- see 9.11
!corrigendum 11.4.3(2)
Replace the paragraph:
with Ada.Exceptions; use Ada; package File_System is type File_Handle is limited private;
by:
package File_System is type File_Handle is limited private;
!corrigendum 11.4.3(6)
Replace the paragraph:
package body File_System is procedure Open(F : in out File_Handle; Name : String) is begin if File_Exists(Name) then ... else Exceptions.Raise_Exception(File_Not_Found'Identity, "File not found: " & Name & "."); end if; end Open;
by:
package body File_System is procedure Open(F : in out File_Handle; Name : String) is begin if File_Exists(Name) then ... else raise File_Not_Found with "File not found: " & Name & "."; end if; end Open;
!corrigendum 12.5.5(1)
!Comment This is a new clause, so this a dummy and the real thing is in the
!comment conflicts.
@dinsa The actual type shall be a limited, task, protected, or synchronized interface if and only if the formal type is also, respectively, a limited, task, protected, or synchronized interface.
@dinss @i<@s8<Examples>>
@xcode<@b<type> Root_Work_Item @b<is tagged private>;>
@xcode<@b<generic>
@b<type> Managed_Task @b<is task interface>; @b<type> Work_Item(<@>) @b<is new> Root_Work_Item @b<with private>;
@b<package> Server_Manager @b<is>
@b<entry> Start(Data : @b<in out> Work_Item);
@b<end> Server;
@b<end> Server_Manager;>
This generic allows an application to establish a standard interface that all tasks need to implement so they can be managed appropriately by an application-specific scheduler.
!corrigendum 12.6(18)
Replace the paragraph:
with function "+"(X, Y : Item) return Item is <>; with function Image(X : Enum) return String is Enum'Image; with procedure Update is Default_Update;
by:
with function "+"(X, Y : Item) return Item is <>; with function Image(X : Enum) return String is Enum'Image; with procedure Update is Default_Update; with procedure Pre_Action(X : in Item) is null; -- defaults to no action with procedure Write(S : not null access Root_Stream_Type'Class; Desc : Descriptor) is abstract Descriptor'Write; -- see 13.13.2 -- Dispatching operation on Descriptor with default
!corrigendum 12.7(11)
Insert after the paragraph:
For the purposes of matching, if the actual instance A is itself a formal package, then the actual parameters of A are those specified explicitly or implicitly in the formal_package_actual_part for A, plus, for those not specified, the copies of the formal parameters of the template included in the visible part of A.
the new paragraphs:
Examples Example of a generic package with formal package parameters:
with Ada.Containers.Ordered_Maps; -- see A.18.6 generic with package Mapping_1 is new Ada.Containers.Ordered_Maps(<>); with package Mapping_2 is new Ada.Containers.Ordered_Maps (Key_Type => Mapping_1.Element_Type, others => <>); package Ordered_Join is -- Provide a "join" between two mappings
subtype Key_Type is Mapping_1.Key_Type; subtype Element_Type is Mapping_2.Element_Type;
function Lookup(Key : Key_Type) return Element_Type;
... end Ordered_Join;
Example of an instantiation of a package with formal packages:
type String_Id is ...
type Symbol_Info is ...
package String_Table is new Ada.Containers.Ordered_Maps (Key_Type => String, Element_Type => String_Id);
package Symbol_Table is new Ada.Containers.Ordered_Maps (Key_Type => String_Id, Element_Type => Symbol_Info);
package String_Info is new Ordered_Join(Mapping_1 => String_Table, Mapping_2 => Symbol_Table);
Apple_Info : constant Symbol_Info := String_Info.Lookup("Apple");
end
Symbol_Package;
!ACATS test
This one is going to be hard to test!
!appendix
```
From: Georg Bauhaus
Sent: Wednesday, August 10, 2005  4:05 PM

!topic mistyped type in example?
!reference Amendmend D12 3.9.4
!discussion

Clause 3.9.4 in Amendment-D12.html presents an example of
a descendant interface, viz. Synchronized_Queue.
Two new primitive operations are to be added. However,
the two procedures following Synchronized_Queue only have
a Queue parameter, not a Synchronized_Queue parameter.
Is this correct?

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

From: Randy Brukardt
Sent: Wednesday, August 10, 2005  4:10 PM

That was noticed during the review of the examples at the York ARG meeting.
(The examples were newly added in April.) There were several dozen changes to
the new examples (all marked as part of AI-433).

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

```

Questions? Ask the ACAA Technical Agent