Version 1.3 of ai12s/ai12-0056-1.txt

Unformatted version of ai12s/ai12-0056-1.txt version 1.3
Other versions for file ai12s/ai12-0056-1.txt

!standard 1.1(3/3)          13-05-01 AI05-0056-1/03
!standard 1.1.2(24/3)
!standard 3.9(12.4/3)
!standard 3.10(22/2)
!standard 5.2(20)
!standard 6.1(39)
!standard A.18.25(10/3)
!standard A.18.26(9.2/3)
!class presentation 12-12-12
!status Amendment 202x 13-01-14
!status work item 13-01-14
!status received 12-11-10
!priority Low
!difficulty Easy
!qualifier Omission
!subject Presentation errors in Ada 2012
!summary
[Editor's note: These changes are included in the draft Standard immediately, as they are considered non-normative and non-controversal. However, they are not yet approved, and thus have more risk of change.]
This AI corrects minor errors in the Standard.
1) Add type Frame to the examples in 3.10.
2) Add an example function with an "in out" parameter to 6.1.
3) Replace the second example of 5.2(20), the current one is not legal.
4) Delete excess "and" from 1.1(3/3).
5) "section" should be "clause" in 1.1.2(24/3).
6) "derived_type_declaration" should be "derived_type_definition" in the syntax font (and have a link) in 3.9(12.4/3).
7) Function Copy in A.18.25(10/3) should return type Tree, not type List.
8) Formal procedure Swap in A.18.26(9.2/3) should have an explicit mode "in" for its parameters.
!question
1) The Next_Frame example in 6.1(39) uses type Frame, which is labeled "see 3.10". But there is no type Frame defined in 3.10. Should there be? (Yes.)
2) Ada 2012 allows functions to have "in out" and "out" parameters, but the examples in 6.1 do not show any such function declarations. Should there be one? (Yes.)
3) If one compiles the second assignment in the example of 5.2(20), my compiler reports "type of aggregate cannot be class-wide". This appears to be correct, the example is wrong as written. Should it be fixed? (Yes.)
4) 1.1(3/3) has an extra "and" preceding "random number generation". Should it be deleted? (Yes.)
5) 1.1.2(24/3) starts "Each section is divided into subclauses...", but of course it is a "clause" that is divided into subclauses. Should this be fixed? (Yes.)
6) In 3.9(12.4/3), "derived_type_declaration" clearly refers to a syntax term, but it is not in the syntax font. Should this be fixed? (Yes.)
7) The function Copy declared in A.18.25(10/3) takes a Tree parameter, but returns a List! There is no List declared in this package; this ought to be Tree, right? (Yes.)
8) Formal procedure Swap in A.18.26(9.2/3) has no explicit mode on its parameters, but our style is to always give an explicit mode on procedure parameters. Should there be an explicit mode "in" here? (Yes.)
!recommendation
(See Summary.)
!wording
1) Add at the start of 3.10(22/2):
type Frame is access Matrix; -- see 3.6
2) Add at the end of 6.1(39):
function Find(B : aliased in out Barrel; Key : String) return Ref_Element; -- See 4.1.5
3) Modify 5.2(20):
Writer := (Status => Open, Unit => Printer, Line_Count => 60); -- see 3.8.1 Next[_Car].all := (72074, null{, Head}); -- see 3.10.1
4) Modify the last sentence of 1.1(3/3):
Finally, a predefined environment of standard packages is provided, including facilities for, among others, input-output, string manipulation, numeric elementary functions, [and ]random number generation, and definition and use of containers.
5) Modify the start of 1.1.2(24/3):
Each {clause}[section] is divided into subclauses ...
6) Modify 3.9(12.4/3):
The function Parent_Tag returns the tag of the parent type of the type whose tag is T. If the type does not have a parent type (that is, it was not {defined}[declared] by a {derived_type_definition}[derived_type_declaration]), then No_Tag is returned.
7) Modify A.18.25(10/3):
function Copy (Source : Tree; Capacity : Count_Type := 0) return {Tree}[List];
8) Modify A.18.26(9.2/3):
with procedure Swap (Left, Right : {in} Index_Type);
!discussion
1) The intent is that the examples in the Standard, taken as a whole, are complete: all of the types and subprograms are defined in (possibly other) examples. (This principle does not apply to examples in AARM notes.)
The use of type Frame in the declaration of Next_Frame violates this principle. Frame was declared in 3.8 in Ada 83, but it was removed from 3.10 (which is what 3.8 became) in Ada 95. This needs to be corrected.
Note that function Next_Frame is used in examples in 4.1.1 and 5.2, so removing it and replacing it by a more typical example is not a good idea.
2) The example functions all have "in" parameters, which shows only a subset of possibilities. We considered replacing Next_Frame (to fix the previous problem) to have a function with an "in out" parameter without making the example larger, but that would have required coming up with a new example for 4.1.1. So we just added a new function here.
The added example includes both an "in out" parameter and an "aliased" parameter, and is a rather typical use of these in a function that returns a generalized reference (similar to the uses in the containers packages).
[Editor's Note: We might want to add an abstract routine as well, or make this one abstract.]
3) The assignment requires a class-wide source object, as the target is class-wide. But it is not legal for an aggregate to have a class-wide type, so we have to qualify the aggregate with a specific type, and then convert that to a class-wide type.
That would require something like:
Next_Car.all := Car'Class(Car'(72074, null))); -- see 3.10.1
This is ugly; moreover, these examples are intended to be very simple (without any conversions) and this surely is not.
Modifying the type of Next_Car would require care as other examples depend upon it. It wouldn't have to be class-wide to make those examples work, but then we'd need a new class-wide example. (And it's nice to show that you can still dereference and access components in a class-wide object.) So that doesn't seem to be a good idea.
Thus, we replace the example completely with one derived from types Cell and Link, and the object Next, conviniently defined directly above the Car example.
4) This is just a left-over word from when that sentence was rewritten at the last moment.
5) This use of "section" was incorrectly changed when "section" was changed into "clause" and "clause" into "subclause" at the direction of ITTF. The command inserted claimed to change it from "clause" to "section", exactly the reverse of what was supposed to happen. (The incorrect command was removed; the Ada 2012 AARM shows an incorrect change which does not match the Ada 2005 Standard.)
6) This is obviously missing formatting, which has been missing since the text was inserted into the Ada 2005 Consolidated Standard. But it probably was mising because there is no such thing as a "derived_type_declaration"; the syntax term is a "derived_type_definition". Then the word "declared" is also wrong, so it was changed to defined.
An alternative wording was considered:
(that is, it is not a derived type)
but this would be a bigger change, and it is not as clear that we're talking about a particular form of type definition. (Not everyone realizes that neither a private extension nor a formal derived type are a derived type, as they certainly look like one. See 3.4(1/2) for the definition of a derived type. This wording depends directly on that definition, as neither of the previously mentioned types has a parent type; the function ignores them when determining its result.)
7) This is pretty clearly a cut-and-paste error, as a similar bullet appears in each of the bounded container sections.
8)
!corrigendum 1.1(3/3)
Replace the paragraph:
The language provides rich support for real-time, concurrent programming, and includes facilities for multicore and multiprocessor programming. Errors can be signaled as exceptions and handled explicitly. The language also covers systems programming; this requires precise control over the representation of data and access to system-dependent properties. Finally, a predefined environment of standard packages is provided, including facilities for, among others, input-output, string manipulation, numeric elementary functions, and random number generation, and definition and use of containers.
by:
The language provides rich support for real-time, concurrent programming, and includes facilities for multicore and multiprocessor programming. Errors can be signaled as exceptions and handled explicitly. The language also covers systems programming; this requires precise control over the representation of data and access to system-dependent properties. Finally, a predefined environment of standard packages is provided, including facilities for, among others, input-output, string manipulation, numeric elementary functions, random number generation, and definition and use of containers.
!corrigendum 1.1.2(24/3)
Replace the paragraph:
Each section is divided into subclauses that have a common structure. Each clause and subclause first introduces its subject. After the introductory text, text is labeled with the following headings:
by:
Each clause is divided into subclauses that have a common structure. Each clause and subclause first introduces its subject. After the introductory text, text is labeled with the following headings:
!corrigendum 3.9(12.4/3)
Replace the paragraph:
The function Parent_Tag returns the tag of the parent type of the type whose tag is T. If the type does not have a parent type (that is, it was not declared by a derived_type_declaration), then No_Tag is returned.
by:
The function Parent_Tag returns the tag of the parent type of the type whose tag is T. If the type does not have a parent type (that is, it was not defined by a derived_type_definition), then No_Tag is returned.
!corrigendum 3.10(22/2)
Replace the paragraph:
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
by:
type Frame is access Matrix; -- see 3.6 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 5.2(20)
Replace the paragraph:
Writer := (Status => Open, Unit => Printer, Line_Count => 60); -- see 3.8.1 Next_Car.all := (72074, null); -- see 3.10.1
by:
Writer := (Status => Open, Unit => Printer, Line_Count => 60); -- see 3.8.1 Next.all := (72074, null, Head); -- see 3.10.1
!corrigendum 6.1(39)
Replace the paragraph:
function Min_Cell(X : Link) return Cell; -- see 3.10.1 function Next_Frame(K : Positive) return Frame; -- see 3.10 function Dot_Product(Left, Right : Vector) return Real; -- see 3.6
by:
function Min_Cell(X : Link) return Cell; -- see 3.10.1 function Next_Frame(K : Positive) return Frame; -- see 3.10 function Dot_Product(Left, Right : Vector) return Real; -- see 3.6 function Find(B : aliased in out Barrel; Key : String) return Real; -- see 4.1.5
!corrigendum A.18.25(10/3)
Replace the paragraph:
function Copy (Source : Tree; Capacity : Count_Type := 0) return List;
by:
function Copy (Source : Tree; Capacity : Count_Type := 0) return Tree;
!corrigendum A.18.26(9.2/3)
Replace the paragraph:
generic type Index_Type is (<>); with function Before (Left, Right : Index_Type) return Boolean; with procedure Swap (Left, Right : Index_Type); procedure Ada.Containers.Generic_Sort (First, Last : Index_Type'Base); pragma Pure(Ada.Containers.Generic_Sort);
by:
generic type Index_Type is (<>); with function Before (Left, Right : Index_Type) return Boolean; with procedure Swap (Left, Right : in Index_Type); procedure Ada.Containers.Generic_Sort (First, Last : Index_Type'Base); pragma Pure(Ada.Containers.Generic_Sort);
!ASIS
No changes needed.
!ACATS test
No test needed.
!appendix

!topic Missing definition of type Frame
!reference 6.1 Subprogram Declarations
!from Pascal Pignard 12-11-10
!discussion

At 6.1_39:
39  ...
        function Next_Frame(K : Positive) return Frame;          --  see 3.10
...

I can't find a definition of type Frame in 3.10 and in all AARM.
Is it an omission?

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

From: Adam Beneschan
Sent: Monday, November 12, 2012 11:21 AM

It was there in the Ada 83 standard (in section 3.8, which was the section on
Access Types that got renumbered to 3.10 in Ada 95).  The examples in 3.10 got
redone in the Ada 95 RM but someone forgot to redo this one in 6.1.

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

From: Adam Beneschan
Sent: Monday, November 12, 2012 11:45 AM

I should point out that there are other references to Next_Frame in examples
elsewhere in the RM.  So maybe the best thing would be to resurrect the definition
of Frame.

The original definition from RM83 3.8(7):

   type FRAME is access MATRIX;  -- see 3.6

Matrix is still present in 3.6 so that should be OK.

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

!topic GNAT compilation error
!reference 5.2 Assignment Statements
!from Pascal Pignard 12-11-10
!discussion

5.2
20     ...
        Next_Car.all := (72074, null);    --  see 3.10.1
GNAT error log:
compute.adb:30:25: type of aggregate cannot be class-wide
compute.adb:30:25: dynamically tagged expression required

I've reconstitute a full test from 5.2_20 and  related:

procedure Compute is
   subtype Month_Name is String (1 .. 3);
   type Gender is (M, F);
   type Date is record
      Day   : Integer range 1 .. 31;
      Month : Month_Name;
      Year  : Integer range 0 .. 4000;
   end record;
   type Person (<>);
   type Person_Name is access Person;
   type Person (Sex : Gender) is record
      Name  : String (1 .. 20);
      Birth : Date;
      Age   : Integer range 0 .. 130;
      case Sex is
         when M =>
            Wife : Person_Name (Sex => F);
         when F =>
            Husband : Person_Name (Sex => M);
      end case;
   end record;
   type Car is tagged
      record
         Number  : Integer;
         Owner  : Person_Name;
      end record;
   type Car_Name    is access all Car'Class;
   Next_Car : Car_Name := new Car;
begin
   Next_Car.all := (72074, null);    --  see 3.10.1 -- line 30
end Compute;

Obviously, suppressing 'Class in type Car_Name removes the errors.
But it is no more conform to 3.10.1_20.

Any idea ?

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

From: Adam Beneschan
Sent: Monday, November 12, 2012 11:41 AM

This is another case of a holdover from Ada 83.  The assignment statement to
Next_Car.all was present in the Ada 83 RM, and of course the Car type wasn't
tagged since tagged types didn't exit.  Car got changed to a tagged type in the
Ada 2005 standard but nobody noticed that this made the example in 5.2 illegal.

I'm not sure what the equivalent example would be; it depends on what the
programmer wants to accomplish.  The issue is that Next_Car's type is unknown
(the compiler can't tell statically what the type will be). Because of that, the
compiler can't determine the meaning of the aggregate.  But this isn't legal
either:

   Next_Car.all := Car'(72074, null);

because of 5.2(6); since the type of the left side is unknown, the rules say
that the right side must be able to dispatch based on the tag of the left side.
This:

   Car(Next_Car.all) := (72074, null);

will set the Number and Owner fields in Next_Car.all; if Next_Car.all's type is
some other type derived from Car, then any fields in a record extension will be
untouched.  I can't think of a simple assignment statement that will assign a
Car value to Next_Car.all if its type is Car, and raise a Constraint_Error if
its type is something else.  If that's what is wanted, I think you have to do
something like:

   if Next_Car.all in Car then
      Car(Next_Car.all) := (72074, null);
   else
      raise Constraint_Error;
   end if;

But I'm guessing that the example in 5.2(20) just needs be dropped, unless we
want to find a case involving an access type dereference that isn't
access-to-classwide.  (The Link type in 3.10.1(15) might work.)

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

From: Erhard Ploederder
Sent: Thursday, December  6, 2012  2:16 PM

!standard Ada2012
!section 1.1 (3)
!subject superfluous "and"

In 1.1.(3) drop the "and" in "...and random number generation."

Reason: there is a subsequent "and" with the container subphrase.

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

From: Randy Brukardt
Sent: Thursday, December 13, 2012 10:26 PM

Erhard Ploedereder sent an editorial on Dec 06, in 1.1(3/3).

Just a bit further, in 1.1.2(24/3), the text starts with "Each section is
divided...", but of course the new text refers to clauses and there aren't any
sections to be seen. (It should say "Each clause is divided...".)

Not sure how I missed either of these. Both will be given the appropriate
priority for fixing. ;-)

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

From: Randy Brukardt
Sent: Thursday, January  3, 2013  8:07 PM

The text for 3.9(12.4/3) says:

The function Parent_Tag returns the tag of the parent type of the type whose tag
is T. If the type does not have a parent type (that is, it was not declared by a
derived_type_declaration), then No_Tag is returned.

but "derived_type_declaration" is not in the syntax font.

This ought to be fixed in the presentation AI (whenever that gets created).
It's been wrong since the Ada 2005 Standard, so the importance level meter is
barely budged...

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

From: John Barnes
Sent: Thursday, April 11, 2013  8:07 PM

A.18.25 (10/3) says that function Copy for a bounded Tree returns a List!!

Maybe we knew that.

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

From: John Barnes
Sent: Wednesday, May  1, 2013  8:07 PM

In A.18.26(9.2/3), the procedure Swap really ought to have mode in on its parameters.

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

Questions? Ask the ACAA Technical Agent