CVS difference for ais/ai-00271.txt

Differences between 1.3 and version 1.4
Log of other versions for file ais/ai-00271.txt

--- ais/ai-00271.txt	2001/09/08 01:42:49	1.3
+++ ais/ai-00271.txt	2001/09/08 03:35:06	1.4
@@ -1,4 +1,4 @@
-!standard 07.01   (02)                                01-06-13  AI95-00271/01
+!standard 07.01   (02)                                01-09-03  AI95-00271/02
 !class amendment 01-05-31
 !status work item 01-06-02
 !status received 01-05-31
@@ -15,184 +15,106 @@
 A package "abstract" is an extract of a package specification, containing
 types, and potentially subpackages, representation items, and static
 constants that may be needed to allow two packages to declare mutually
-recursive types.  A package abstract is referenced by an "abstract with"
-clause.  A package specification must conform to its package abstract,
+recursive types. A package abstract is referenced by an "abstract with"
+clause. A package specification must conform to its package abstract,
 if any.
 
 !problem
 
 Ada only allows mutually recursive types to be declared if they
-are all declared within the same library unit.  This can force
+are all declared within the same library unit. This can force
 all of the major data structures of a program into a single library unit,
 which is clearly undesirable in some situations.
 
+The goal of the proposed features is to allow mutual recursion among separately
+compiled types (types containing (pointers to) each other as components, and
+primitive operations with (pointers to) each other as parameters.) And to do
+this in a way that doesn't place any other restrictions on the programmer.
+
 !proposal
 
-Three new constructs are proposed: a package_abstract, a with_abstract
+Three new constructs are proposed: a package "abstract," a "with abstract"
 clause, and an incomplete tagged type.
 
-
 PACKAGE ABSTRACT:
-
-A package_abstract has the following syntax:
 
-    package_abstract ::= library_package_abstract |
-                         nested_package_abstract
+    package_abstract ::=
+        PACKAGE ABSTRACT defining_program_unit_name IS
+            {package_abstract_item}
+        END [[parent_unit_name.]identifier];
 
-    library_package_abstract ::=
-        ABSTRACT
-            {abstract_item}
+    package_abstract_item ::=
+        {basic_declarative_item | package_abstract}
 
-    nested_package_abstract ::=
-        ABSTRACT
-            {abstract_item}
-        PACKAGE defining_identifier ;
+A package abstract is a new kind of library unit:
 
-The syntax for library_unit_declaration is amended as follows:
-
     library_unit_declaration ::=
-        subprogram_declaration |
-        [library_package_abstract] package_declaration |
-        generic_declaration |
-        generic_instantiation
-
-In other words, a package_abstract is only allowed before a library unit
-declaration for a non-generic package.  The reason for this restriction is
-as follows:
-
-   - Subprogram_declarations do not export types or constants.
-
-   - Generic_declarations and generic_instantiations cannot participate in
-     circular dependencies.
-
-   - The abstracts for nested packages are given as nested abstracts in the
-     top-level abstract.  That's because we want abstracts to be entered
-     "early" in the environment.  If nested packages had abstracts, they
-     would have to be entered "early" too.  But then they could depend on
-     declarations appearing earlier in the same library unit declaration,
-     so this library unit declaration would have to be partially processed
-     by the compiler, and we don't know how to specify this in a way that
-     works for both source-based and library-based compilers.
-
-A package abstract may contain only the following kinds of declarative items:
-
-   abstract_item ::=
-       incomplete_type_declaration
-     | abstract_interface_declaration    -- see AI-251 on interface types
-     | TYPE defining_identifier IS access_type_definition ;
-     | defining_identifier_list : CONSTANT [subtype_indication]
-         := static_expression ;
-     | attribute_definition_clause
-     | nested_package_abstract
-
-Representation pragmas are also permitted.
-
-No pool-specific access types may be declared in a package abstract.
+        subprogram_declaration | package_abstract | package_declaration |
+        generic_declaration | generic_instantiation
 
-All expressions appearing in a package_abstract must be static.
+An incomplete type declared in a package_abstract need not have a completion in
+the abstract.  Because a package_abstract has only one list of declarations (no
+private part), things like private types, private extensions, and deferred
+constants are illegal in an abstract.
 
 The specification of a package must "conform" to its abstract, if any,
 in the following sense:
 
-   - Each incomplete type declaration must be completed in the visible
-     part of the specification of the package by a full_type_declaration,
-     a private_type_declaration, or a private_extension_declaration.
-
-   - For each nested_package_abstract, there must be a
-     package_specification with the same defining_identifier in the
-     visible part of the specification of the package.  This package must
-     in turn conform to its abstract.  (This wording is probably not quite
-     right, but the purpose should be clear.)
-
-If an access type is declared in a package abstract, all aspects of
-its representation except for its storage pool are frozen at the end
-of the package abstract.  As indicated above, the access type
-must not be pool-specific.
-
-The only representation items permitted in the package specification
-for the access type are those that apply to the storage
-pool of the type (Storage_Pool, Storage_Size).
-
-The elaboration of a package abstract has no effect.
-
-The actual "collection" for the access type is not created until
-the package specification is elaborated.  An allocator is illegal for an
-access type declared in an abstract, though not for the corresponding
-access type declared in the specification.  Similarly, an access
-type in an abstract must not be passed as an actual for a formal
-access type in a generic instantiation.
+   - Each incomplete type declaration in the abstract of a package must be
+     completed in the visible part of the specification of the package, unless
+     it was completed in the abstract. This completion may be a
+     private_type_declaration or a private_extension_declaration.
+
+   - Each nested package abstract must be completed in the visible part of the
+     specification by a nested package. This nested package must conform to its
+     abstract.
+
+The completion of a (library-level) private package_abstract must be a private
+package. The completion of a public package_abstract must be a public package.
+
+All the entities declared in package_abstract become frozen at the end of the
+abstract, except for incomplete types.
+
+Each library-level package which has no explicit abstract is assumed to have an
+empty package_abstract with nested package_abstracts appropriate for each
+package nested in the visible part of the package.
 
 
 WITH ABSTRACT CLAUSE:
 
-   with_clause ::= with_abstract_clause | with_unit_clause
-
-   with_unit_clause ::= WITH library_unit_name {, library_unit_name}
-
    with_abstract_clause ::=
-       WITH ABSTRACT library_unit_package_name {, library_unit_package_name};
-
-[Anyone has a better name for with_unit_clause?]
+       WITH library_unit_package_name ABSTRACT
+            {, library_unit_package_name ABSTRACT};
 
-The scope of a with_abstract_clause that appears on a
-library_unit_declaration which is a package_declaration with a
-library_package_abstract consists only of the declarative region of the
-package_declaration.  The declarative region of the
-library_package_abstract is not included.  [Otherwise we are back to a
-circularity where two packages that have abstracts cannot depend on
-each other.]
-
-The scope of a with_unit_clause that appears on a
-library_unit_declaration which is a package_declaration with a
-library_package_abstract consists of the declarative region of the
-library_package_abstract (which in turns include the package_declaration,
-etc.).
-
-A with_abstract_clause on a compilation unit makes the abstract (and only
-the abstract) of each specified package visible within the compilation
-unit.  It has no effect if the specification of the package is visible due
-to a with clause on some ancestor (or corresponding declaration) of the
-compilation unit.
+A with_abstract_clause on a compilation unit makes the abstract of each
+specified package visible within the compilation unit. A (normal) with clause
+on a compilation unit makes the specification and the abstract visible.
+Consider the case where package P has an abstract which declares an incomplete
+type T. At a place where only the abstract of P is visible, the name P.T
+designates an incomplete type, and the restrictions of RM95 3.10.1 apply.
+At a place where the specification of P is visible, the name P.T designates
+a complete type, and the restrictions of RM95 3.10.1 are not applicable.
+
+A with_abstract_clause specifying a package which has no (explicit) abstract
+has no effect.
+
+Within the abstract of a child package the abstract of its parent is directly
+visible.  Within the specification of a child package, the abstract of its
+parent is directly visible.
 
-A with_unit_clause on a compilation unit makes both the abstract and the
-visible part of each specified package visible within the compilation unit.
-
-Within the abstract for a child package, the abstract of its ancestors,
-if any, is directly visible.
-
 If a package specified by a with_abstract_clause on some compilation unit
-is a child package, then the abstract of its parent and each further
-ancestor is made visible as if it were denoted by an explicit
-with_abstract_clause.
-
-If an abstract or specification of a package is made visible by an abstract
-with clause, then a semantic dependence is created on that part of the
-package.  [This in turn implies an elaboration dependence -- see 10.2(9).]
-The specification of a package has a semantic dependence on its abstract,
-if any.
+is a child package, then the abstracts of its parent and each further
+ancestor are made visible within the compilation unit.
 
-The compilation model for abstracts is as follows:
+If a package_abstract is made visible by a with_abstract_clause, then a
+semantic dependence is created on that part of the package.  [This in turn
+implies an elaboration dependence -- see 10.2(9).] The specification of a
+package has a semantic dependence on its abstract, if any.
+
+[TBD: We should probably have incomplete-types-completed-by-private-types even
+in a vanilla package visible part.]
+[TBD: Should "package abstract P renames Q;" be supported?  Seems OK.]
 
-   - Adding a package_abstract to the environment causes the compiler to
-     process only the library_package_abstract part of the unit.
-
-   - Adding a library_unit_declaration which includes a package_declaration
-     to the environment causes the compiler to process both the
-     library_package_abstract and the package_declaration.
-
-   - When a library_unit_declaration is compiled, and the environment
-     already contains a package_abstract for the same unit, and that
-     abstract doesn't conform to the abstract of the unit being compiled,
-     the compiler may remove the existing package_abstract from the
-     environment.  It is _not_ allowed to do this if the
-     library_unit_declaration has a package_abstract which conforms to
-     the one already entered in the environment.
-
-   - Post-compilation rule: it shall not be possible to run a partition
-     that contains a package_abstract and a package_specification which do
-     not conform to each other.
-
-
 INCOMPLETE TAGGED TYPE:
 
    incomplete_type_declaration ::=
@@ -200,10 +122,10 @@
 
 An incomplete tagged type may be used as the type of a formal parameter
 prior to its completion, in addition to the normal places where
-an incomplete type may be used.  Also, the Class attribute is defined for
-an incomplete tagged type.  The class-wide type denoted by the Class
+an incomplete type may be used. Also, the Class attribute is defined for
+an incomplete tagged type. The class-wide type denoted by the Class
 attribute of an incomplete type may also be used as the type of a
-formal parameter.  The Class attribute of a non-tagged incomplete
+formal parameter. The Class attribute of a non-tagged incomplete
 type would be considered obsolescent.
 
 Note that we are not proposing that an incomplete tagged type may be
@@ -216,13 +138,13 @@
 !discussion
 
 The concept of a package abstract has been discussed before, under
-different guises.  At the time, the "with type" seemed somewhat more
-attractive.  However, various technical difficulties associated with
+different guises. At the time, the "with type" seemed somewhat more
+attractive. However, various technical difficulties associated with
 making access types visible via "with type" have reduced the
-capability of the "with type" proposal.  Also, implementation discussions
+capability of the "with type" proposal. Also, implementation discussions
 about how to implement "with type" have revealed some significant issues
 associated with whether or not the specification must be in the
-environment prior to compiling a "with type" clause.  Other problems
+environment prior to compiling a "with type" clause. Other problems
 that have arisen relate to the need to implicitly create an "abstract"
 for a package to implement "with type," with the attendant issues associated
 with implicit structures in the program library, their longevity, their
@@ -230,10 +152,10 @@
 strange "fictions" to explain to the user what is really going on.
 
 There seem to be two general ways this kind of problem is solved in
-other languages.  One approach is to permit unrestricted forward
-references.  This is the approach adopted by Eiffel, Java, and Smalltalk.
+other languages. One approach is to permit unrestricted forward
+references. This is the approach adopted by Eiffel, Java, and Smalltalk.
 The other approach is to require "forward" or "incomplete" declarations,
-sometimes called "signatures" or "partial revelations."  This is generally
+sometimes called "signatures" or "partial revelations." This is generally
 the approach adopted by Ada, as well as Pascal, Modula, ML, C/C++, etc.
 The notion of a package "abstract" is analogous to the "incomplete"
 type in Ada, the signature in ML, and the partial revelation in Modula.
@@ -248,21 +170,20 @@
 the user something to look at and conceptually "hold onto," which
 should make the concept easier to understand.
 
-We considered separating the abstract and making it a new kind of
-library unit.  However, this would have a significant impact on the
-tools which deal with the enviroment and the library units, in addition to
-the impact on the compiler proper.  By putting the abstract in the same
-library unit as the specification, we are avoiding the extra burden of
-a new kind of unit.  However, we need to define a two-phase compilation
-process, where the abstract is entered in the environment on a reference
-through a with_abstract_clause, and the specification is entered in the
-environment on a reference through a normal with clause.
-
-From an implementation point of view, the "optionality" of a package
-abstract is somewhat analogous to the "optionality" of a subprogram
-specification.  The two-phase compilation process is somewhat analogous to
-the two-phase process that has to take place to support mutual inlining
-(an optional capability).
+From an implementation point of view, the "optionality" of a package abstract
+is analogous to the "optionality" of a subprogram specification, and presumably
+similar program library mechanisms can be used to accommodate them.
+
+Currently, a package has three parts: visible part, private part, and body.
+The visible and private parts are syntactically combined, because the compiler
+needs to see them both at once, in order to generate reasonably efficient code.
+More precisely, when compiling a compilation_unit that says "with P;" the
+compiler needs to look at both the visible and private parts of P.
+
+This proposal adds another part, so we have four: abstract, visible part,
+private part, and body. In terms of syntax, these form *three* compilation
+units: abstract, spec, and body. The visibility rules work as usual,
+considering an abstract to come before the visible part/private part/body.
 
 !example
 
@@ -270,38 +191,34 @@
 belongs to a particular department, and a department has a manager who
 is an employee.
 
-    with abstract Departments;
-    abstract
+    package abstract Employees is
         type Employee;
         type Emp_Ptr is access all Employee;
+    end Employees;
+
+    package abstract Departments is
+        type Department;
+        type Dept_Ptr is access all Department;
+    end Departments;
+
+    with Departments abstract;
     package Employees is
         type Employee is private;
+        type Emp_Ptr is access all Employee;
         procedure Assign_Employee(E : access Employee;
                                   D : access Departments.Department);
         ...
-        function Current_Department(D : access constant Employee)
-                                    return Departments.Dept_Ptr;
-    private
-        type Employee is
-            record
-                Assigned_To : Departments.Dept_Ptr;
-            end record;
+        function Current_Department(D : access constant Employee) return
+            Departments.Dept_Ptr;
     end Employees;
 
-    with abstract Employees;
-    abstract
-        type Department;
-        type Dept_Ptr is access all Department;
+    with Employees abstract;
     package Departments is
         type Department is private;
+        type Dept_Ptr is access all Department;
         procedure Choose_Manager(D : access Department;
                                  Manager : access Employees.Employee);
         ...
-    private
-        type Department is
-            record
-                Manager : Employees.Emp_Ptr;
-            end record;
     end Departments;
 
 !ACATS test

Questions? Ask the ACAA Technical Agent