CVS difference for ais/ai-00348.txt

Differences between 1.6 and version 1.7
Log of other versions for file ais/ai-00348.txt

--- ais/ai-00348.txt	2003/10/29 00:40:58	1.6
+++ ais/ai-00348.txt	2003/12/07 05:00:33	1.7
@@ -1,4 +1,4 @@
-!standard  6.07(00)                                     03-10-23  AI95-00348/05
+!standard  6.07(00)                                     03-12-04  AI95-00348/05
 !standard  3.01(09)
 !standard  7.06(06)
 !standard  7.06(08)
@@ -18,8 +18,26 @@
 
 !summary
 
-This proposal adds "null procedures" to the standard.
+A new form of procedure declaration, a null procedure, is
+added to the language. Its effect is that of a procedure
+whose body comprises just a null statement. Null procedures
+are important for abstract interfaces (see AI-251). They are
+also useful for generic defaults and in simplifying
+Ada.Finalization.
 
+!problem
+
+It currently is impossible to change an abstract tagged type to an
+abstract interface (see AI-251) if the abstract tagged type has any
+concrete subprograms. Many such subprograms exist only to give a default
+(empty) implementation so that the standard "pass-the-buck" implementation
+is always possible. (This means that the implementation of an overriding
+operation always calls the overridden operation of the parent type.) This is
+especially an issue in generic units, where the overriding routine must
+"pass-the-buck", since it can assume nothing about the implementation.
+
+!proposal
+
 A "null procedure" is a procedure declaration of the (newly
 introduced) form
 
@@ -34,42 +52,41 @@
 
 The use of "null" as a default for generic formal procedures is also supported.
 
-!problem
-
-Null procedures are a prerequisite for AI-251 (abstract interfaces); see
-the discussion section below.
-
-They are also be useful in the specification of Ada.Finalization.
 
-!proposal
-
-(See wording.)
-
 !wording
-
-3.1 Declarations
 
-Add to syntax (paragraph 3)
+Add to 3.1(3):
 
     basic_declaration ::= ... | null_procedure_declaration
 
 
+Add a new clause 6.7:
+
 6.7  Null Procedures
 
+    A null_procedure_declaration provides a shorthand to declare a procedure
+    with an empty body.
+
                               Syntax
 
     null_procedure_declaration ::= procedure_specification IS NULL;
 
                               Static Semantics
 
-    A null_procedure_declaration declares a null procedure.
+    A null_procedure_declaration declares a null procedure. [A completion is
+    not allowed for a null_procedure_declaration.]
 
+    AARM Proof: A null_procedure_declaration is not a subprogram_declaration,
+    thus it does not require or allow completion.
+
                               Dynamic Semantics
 
     The execution of a null procedure is invoked by a subprogram call.
-    The execution of the subprogram_body of a null procedure has no
-    effect.
+    For the execution of a subprogram call on a null procedure,
+    the execution of the subprogram_body has no effect.
 
+    AARM Note: A null procedure has no subprogram_body; but we need to explain
+    what the subprogram_body mentioned in 6.4's Dynamic Semantics does.
 
 Replace 7.6(6) with
     procedure Initialize (Object : in out Controlled) is null;
@@ -105,43 +122,24 @@
 AARM Proof: This follows from 6.3.1(7).
 
 !discussion
-
-Like an instantiation, a null procedure is not allowed as a completion.
-Allowing this would double the amount of RM text needed for no real gain.
-
-Like an instantiation, a null procedure does not "require completion".
 
-A null procedure may have OUT-mode parameters, just as a
-"begin null; end;" procedure may. Note that copyback is performed in this
-case, just as for a "begin null; end;" procedure. The phrase
-"The execution of the subprogram_body" in the dynamic semantics section
-refers to 6.4(10)'s "The subprogram_body is then executed",
-which is just one of the steps in the execution of a subprogram call.
-The call as a whole may have a user-visible side-effect (e.g. trashing
-a scalar out parameter); it is only the "execution of the subprogram_body"
-step of the call which has no effect.
+Null procedures make interface types (AI-251) much more useful. The ability to
+declare a primitive of an interface as a null procedure enables existing
+abstract types that have null (non-abstract) default implementations of some of
+their primitives to be transitioned to being interface types. An example of
+such a type is Ada.Finalization.Controlled. There are other considerations
+which argue for leaving Controlled as a "normal" tagged type, but the
+capability of switching other existing abstract tagged types to be interfaces
+remains potentially quite useful.
 
-The changes to Ada.Finalization are not an essential part of this AI.
-
 Although the primary motivation for null procedures is for use with interface
-types (AI-251), they are also useful in other contexts. For code in a generic
+types, they are also useful in other contexts. For code in a generic
 which always "passes the buck" to the corresponding parent primitive (as is
 done for Finalize, for example), the compiler can eliminate such a call when
 the parent's operation is known to be null at instantiation time.
 There are obvious documentation advantages for someone extending
 a type to know that the default implementation of an operation is null.
 
-Null procedures make interface types much more useful.
-
-The ability to declare a primitive of an interface as a null procedure
-enables existing abstract types that have null (non-abstract) default
-implementations of some of their primitives to be transitioned to being
-interface types. An example of such a type is
-Ada.Finalization.Controlled. [Note that there are other
-considerations which might argue for leaving Controlled as a "normal" tagged
-type, but the capability of switching other existing abstract tagged types to
-be interfaces remains potential quite useful, in our view.]
-
 The ability to have non-dispatching calls on the primitive of a generic
 formal interface type to be made inside the generic can be necessary to
 enable a pass-the-buck-to-the-parent paradigm when overriding the
@@ -159,25 +157,23 @@
      package P is
          type NN is new NT with private;
          procedure Prim1(X : NN);
-             -- may "pass-the-buck" to Prim1 of NT as part
-             -- of implementation of Prim1 of NN.
+             -- May "pass-the-buck" to Prim1 of NT as part
+             -- of implementation of Prim1 of NN
          procedure Prim2(X : NN);
              -- Prim2 must be overridden;
-             -- cannot call Prim2 of NT since might be abstract
+             -- cannot call Prim2 of NT since it might be abstract
      end P;
 
---------
 
-Null procedures are distinct subprograms in the sense of 4.5.2(13).
-This means that in this example
+Consider the following:
 
   package Pkg1 is
     procedure P is null;
-  end P1;
+  end Pkg1;
 
   package Pkg2 is
     procedure P is null;
-  end;
+  end Pkg2;
 
   with Pkg1, Pkg2;
   package Pkg3 is
@@ -185,14 +181,45 @@
     Ptr1 : Ref := Pkg1.P'access;
     Ptr2 : Ref := Pkg2.P'access;
     Eq : constant Boolean := Ptr1 = Ptr2;
-  end;
+  end Pkg3;
 
-Eq must be False.
+Null procedures are distinct subprograms in the sense of 4.5.2(13), so as
+a consequence the Boolean Eq must be false.
 
-The convention of a formal procedure whose default is null and actual is
+The convention of a formal procedure whose default is null and whose actual is
 omitted is Intrinsic. This follows from 6.3.1(7). Thus we don't have to worry
 about access issues for such formal subprograms.
 
+Like an instantiation, a null procedure is not allowed as a completion.
+Allowing this would double the amount of RM text needed for no real gain.
+
+Like an instantiation, a null procedure does not "require completion".
+
+A null procedure may have OUT-mode parameters, just as a regular procedure may.
+Since
+
+   procedure Piglet(X: out T) is
+   begin
+       null;
+   end Piglet;
+
+is legal,
+
+   procedure Piglet(X: out T) is null;
+
+is also allowed. Note that copyback is performed in this case, just as for a
+regular procedure. The phrase "The execution of the subprogram_body" in the
+dynamic semantics section refers to "The subprogram_body is then executed" from
+clause 6.4(10), which is just one of the steps in the execution of a subprogram
+call. The call as a whole may have a user-visible side-effect (e.g. copying
+junk into the actual of a scalar out parameter); it is only the "execution of
+the subprogram_body" step of the call which has no effect.
+
+The changes to Ada.Finalization are not an essential part of this AI, but
+using syntax is clearer than using text to describe the semantics of these
+routines.
+
+
 !example
 
     package Pkg is
@@ -222,6 +249,9 @@
 
 @dinsc
 
+A @fa<null_procedure_declaration> provides a shorthand to declare a procedure
+with an empty body.
+
 @i<@s8<Syntax>>
 
 @xcode<@fa<null_procedure_declaration ::= procedure_specification >@ft<@b<is null>>@fa<;>>
@@ -229,11 +259,13 @@
 @i<@s8<Static Semantics>>
 
 A @fa<null_procedure_declaration> declares a @i<null procedure>.
+A completion is not allowed for a @fa<null_procedure_declaration>.
 
 @i<@s8<Dynamic Semantics>>
 
 The execution of a null procedure is invoked by a subprogram call.
-The execution of the @fa<subprogram_body> of a null procedure has no effect.
+For the execution of a subprogram call on a null procedure, the execution of
+the @fa<subprogram_body> has no effect.
 
 !corrigendum 7.6(6)
 

Questions? Ask the ACAA Technical Agent