Version 1.6 of ai12s/ai12-0080-1.txt

Unformatted version of ai12s/ai12-0080-1.txt version 1.6
Other versions for file ai12s/ai12-0080-1.txt

!standard 3.9.3(6/2)          14-03-31 AI05-0080-1/04
!standard A.18.26(29/3)
!standard A.18.26(31/3)
!standard B.1(50)
!standard N(21.2/3)
!class presentation 13-10-21
!status Corrigendum 2014 13-12-11
!status work item 13-10-21
!status received 13-06-16
!priority Low
!difficulty Easy
!qualifier Clarification
!subject More 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) An abstract function inherited for a null extension still requires overriding.
2) The examples in B.1 are of interfacing aspects, of course.
3) "An invariant" rather than "A invariant".
4) Drop ".all" from the Edge renaming in the containers example.
!question
1) The following appears to be legal:
package Pack1 is type T1 is abstract tagged record ... end record; function Create (N : Integer) return T1 is abstract; end Pack1;
package Pack2 is type T2 is new Pak1.T1 with private; private type T2 is new Pak1.T1 with null record; end Pack2;
as Create is "a function with a controlling result" inherited by a private extension, as described in 3.9.3(6). But Create is abstract, and we don't want abstract subprograms of nonabstract tagged types. Should this be fixed? (Yes.)
2) B.1(50) says that the examples are of "interfacing pragmas", but all of the following examples are of "interfacing aspects". Should this be fixed? (Yes.)
3) N(21.2/3) start "A invariant". That should be "An invariant", right? (Yes.)
4) The Edge renaming in A.18.32(29/3) and A.18.32(31/3) ends with ".all". But a generalized reference is itself a dereference; it's not a pointer that needs to be dereferenced. Should the ".all" be deleted? (Yes.)
!recommendation
(See Summary.)
!wording
1) Modify 3.9.3(6/2):
Otherwise, the subprogram shall be overridden with a nonabstract subprogram or, in the case of a private extension inheriting a {nonabstract} function with a controlling result, have a full type that is a null extension; for a type declared in the visible part of a package, the overriding may be either in the visible or the private part. Such a subprogram is said to @i<require overriding>. However, if the type is a generic formal type, the subprogram need not be overridden for the formal type itself; a nonabstract version will necessarily be provided by the actual type.
2) Modify B.1(50):
Example of interfacing {aspects}[pragmas]:
3) Modify N(22.2/4):
Invariant. {An}[A] invariant is an assertion...
4) Modify A.18.32(29/3):
...
E : Edge renames G (Next)(C)[.all];
...
Modify A.18.32(31/3):
...
E : Edge renames L(C)[.all];
...
!discussion
1) This problem was noted in the e-mail appendix to AI95-00391-1 (which originally defined this wording), but for some reason the fix was never applied. It obviously would make no sense to allow an abstract routine to be inherited but not be overridden for a nonabstract type (of any kind).
2) Since the clause title is "Interfacing aspects", it's pretty clear what the intent is!
3) "An" should proceed nouns that start with vowel sounds, as in this case.
4) Since a generalized reference is not (usually) a pointer, it can't (usually) be dereferenced. So ".all" doesn't make sense in this example.
!corrigendum 3.9.3(6/2)
Replace the paragraph:
by:
!corrigendum A.18.32(29/3)
Replace the paragraph:
for C in G (Next).Iterate loop declare E : Edge renames G (Next)(C).all; begin if not Reached(E.To) then ... end if; end; end loop;
by:
for C in G (Next).Iterate loop declare E : Edge renames G (Next)(C); begin if not Reached(E.To) then ... end if; end; end loop;
!corrigendum A.18.32(31/3)
Replace the paragraph:
declare L : Adjacency_Lists.List renames G (Next); C : Adjacency_Lists.Cursor := L.First; begin while Has_Element (C) loop declare E : Edge renames L(C).all; begin if not Reached(E.To) then ... end if; end; C := L.Next (C); end loop; end;
by:
declare L : Adjacency_Lists.List renames G (Next); C : Adjacency_Lists.Cursor := L.First; begin while Has_Element (C) loop declare E : Edge renames L(C); begin if not Reached(E.To) then ... end if; end; C := L.Next (C); end loop; end;
!corrigendum B.1(50)
Replace the paragraph:
Example of interfacing pragmas:
by:
Example of interfacing aspects:
!corrigendum N(21.2/3)
Replace the paragraph:
Invariant. A invariant is an assertion that is expected to be True for all objects of a given private type when viewed from outside the defining package.
by:
Invariant. An invariant is an assertion that is expected to be True for all objects of a given private type when viewed from outside the defining package.
!ASIS
No changes needed.
!ACATS test
No test needed.
!appendix

!topic Missing word in 3.9.3(6)?
!reference 3.9.3(6)
!from Adam Beneschan 13-08-08
!discussion

3.9.3(6) says:

    Otherwise, the subprogram shall be overridden with a nonabstract
    subprogram or, in the case of a private extension inheriting a
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    function with a controlling result, have a full type that is a
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        
    null extension; for a type declared in the visible part of a
    package, the overriding may be either in the visible or the
    private part. Such a subprogram is said to require
    overriding. However, if the type is a generic formal type, the
    subprogram need not be overridden for the formal type itself; a
    nonabstract version will necessarily be provided by the actual
    type.

Shouldn't the clause I marked say

    or, in the case of a private extension inheriting a
    **nonabstract** function with a controlling result, ...

?  The intent is obviously that private extensions whose full type is
a null extension don't have to override functions with controlling
results.  But a function with a controlling result could also be
abstract, and we don't want the rule to apply in that case.  Otherwise
I think this would be legal:

    package Pack1 is
        type T1 is abstract tagged record ... end record;
        function Create (N : Integer) return T1 is abstract;
    end Pack1;

    package Pack2 is
        type T2 is new Pak1.T1 with private;
    private
        type T2 is new Pak1.T1 with null record;
    end Pack2;

It's really a bit of a nitpick since the intent is obvious, but I
think it should be corrected.

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

From: Adam Beneschan
Sent: Thursday, August 8, 2013  8:01 PM

Heh... I just noticed (9 years after the fact) that Tucker mentioned this
at the end of AI95-391, but apparently it didn't get in ...

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

From: Randy Brukardt
Sent: Friday, September 27, 2013  7:51 PM

B.1(50) says "examples of interfacing PRAGMAS", but the examples are all of
aspects. Grump.

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

From: John Barnes
Sent: Saturday, January 18, 2014  10:26 AM

How is the cold out there?  It's just so wet here.

Anyway, you don't want to know this but the Ada 2012 Glossary has
"A invariant ..." which should be "An invariant ...".

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

Summary of private conversation, March 29-31:

Ed Schonberg: Reference returns a type to which an implicit
dereference can be applied, but it certainly cannot be dereferenced
explicitly.

Randy Brukardt: Arghh! For some reason, I thought a generalized reference
returned an access value, not an object. 4.1.5(6/3) clearly says that it
is an object (obtained via a dereference). At least the example A.18.32
(paragraphs 29 and 31) are wrong this way, as are a lot of my other examples
in e-mail and those I created for John in the Rationale.

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

Questions? Ask the ACAA Technical Agent