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

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

!standard 1.1(3/3)          13-07-03 AI12-0056-1/05
!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 6.2(13)
!standard A.18.25(10/3)
!standard A.18.26(9.2/3)
!class presentation 12-12-12
!status Corrigendum 1-2012 13-01-14
!status WG9 Approved 13-11-15
!status ARG Approved 9-0-0 13-06-15
!status work item 13-01-14
!status received 12-11-10
!priority Low
!difficulty Easy
!qualifier Omission
!subject Presentation errors in Ada 2012
!summary
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.
9) Add two user notes in 6.2 to point at where the rules about parameter modes really are.
!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.)
9) 6.2 is titled "Formal parameter modes". But nothing in this clause is about parameter modes other than the introduction 6.2(1) and the note 6.2(13). Should we do more? (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);
9) Add new notes on either side of 6.2(13):
{The mode of a formal parameter describes the direction of information transfer to or from the subprogram_body (see 6.1).}
A formal parameter of mode in is a constant view (see 3.3); it cannot be updated within the subprogram_body.
{A formal parameter of mode out might be uninitialized at the start of the subprogram_body (see 6.4.1).}
!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) Our standard style has modes on all procedure parameters, so this one should as well.
9) This clause got its name from Ada 83, when it really did define the formal parameter modes. But the normative rules all have moved away. In order for the Standard to live up to its name ("Ada Reference Manual"), we at least should have some references to the actual normative rules. Since a note already provides one such reference, we add two more notes to give the other two for the other most important rules.
!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 6.2(13)
Replace the paragraph:
NOTES
6 A formal parameter of mode in is a constant view (see 3.3); it cannot be updated within the subprogram_body.
by:
NOTES
6 The mode of a formal parameter describes the direction of information transfer to or from the subprogram_body (see 6.1).
7 A formal parameter of mode in is a constant view (see 3.3); it cannot be updated within the subprogram_body.
8 A formal parameter of mode out might be uninitialized at the start of the subprogram_body (see 6.4.1).
!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.

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

From: Randy Brukardt
Sent: Friday, February 22, 2013  3:52 PM

Steve Baird pointed out as an "observation" that 6.2, Formal Parameter Modes,
doesn't actually contain any rules about formal parameter modes; the only
mention of modes is in the non-normative introductory text and in a note.

The actual definitions and important rules for formal parameter modes are in
6.1(18) [the definition]; 3.3(17) [in mode is a constant]; and 6.4.1(12-15)
[out parameters might not be initialized].

Since we usually call this document the Ada REFERENCE Manual, one would hope
that it could be used for - ahem - reference. As such, a section called
"formal parameter modes" ought to at least mention the important rules about
formal parameter modes and provide cross-references, even if it isn't an
appropriate place anymore for the actual rules.

[Aside: This name comes from the Ada 83 standard, where it actually defined
the meaning of these modes. That got moved to 6.1 in Ada 9x, but the name of
the clause remained unchanged.]

We could of course change the name of the clause (to something like "parameter
passing mechanisms"), but then the introduction and note don't really fit.

A better approach is to add notes cross-referencing the other important rules
for "formal parameter modes". Something like (the second note is the one that
already exists):

Notes

{The mode of a formal parameter describes the direction of information transfer
to or from the subprogram_body (see 6.1).}

A formal parameter of mode *in* is a constant view (see 3.3); it cannot be
updated within the subprogram_body.

{A formal parameter of mode *out* may be partially or completely uninitialized
at the start of the subprogram_body (see 6.4.1).}

---

As notes are non-normative, we can add them as part of the presentation AI (thus,
no separate AI is needed).

Obviously, this proposed change does not meet the Duff rule of relevance, so I
have to presume Bob is against it. Is that a general opinion or should I stick
this into the presentation AI??

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

From: Bob Duff
Sent: Friday, February 22, 2013  4:04 PM

> Obviously, this proposed change does not meet the Duff rule of 
> relevance, so I have to presume Bob is against it.

You know me well.

I'm even against answering emails about it.

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

From: Randy Brukardt
Sent: Friday, February 22, 2013  4:20 PM

Which you just did. :-) This seems like an Onion headline: "Bob Duff opposes
own actions!" :-) :-)

P.S. Sorry, it's Friday. ;-)

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

Questions? Ask the ACAA Technical Agent