CVS difference for ais/ai-40217.txt

Differences between 1.1 and version 1.2
Log of other versions for file ais/ai-40217.txt

--- ais/ai-40217.txt	2003/01/24 04:09:59	1.1
+++ ais/ai-40217.txt	2003/02/01 04:40:34	1.2
@@ -4934,3 +4934,2338 @@
 
 *************************************************************
 
+From: Robert Dewar
+Sent: Thursday, January 23, 2003  11:19 PM
+
+> I guess I am surprised that large systems
+> don't use a package hierarchy already,
+> with nearly empty "root" packages.
+
+Seeing as many large Ada programs are derived from legacy Ada 83 systems,
+you should not be so surprised. In fact I have seen very few of the large
+systems we deal with structured this way.
+
+*************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Friday, January 24, 2003  1:49 AM
+
+> I agree it would be great if we could have stand-alone
+> package prefixes, but the impact of that just seemed
+> very large last time we visited it.  Perhaps we could design a syntax
+> for stand-alone prefixes, but focus on getting the nested ones
+> approved, and then work on determining the implementation impact
+> of having stand-alone ones.  I really think the nested ones are
+> relatively simple to implement, whereas the stand-alone ones imply
+> a new kind of compilation unit, a new kind of "with" clause, new
+> library-item elaboration-order issues, and generally a lot more effort and complexity.
+>
+Well... Thinking about it.
+There is no circular dependency problem if all packages are nested within one
+big package. The only new possibility of this solution is to separate (part of)
+the specification. Separating the body was of course already possible.
+
+The question is: will the people who were unhappy with the nested packages
+solution be willing to accept this one?
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, January 24, 2003  3:55 AM
+
+Bob E. argued:
+
+> project, you don't model the solution, you model the problem space.  To
+> use the example of a directory system, any solution that makes people
+> subordinate to offices, or offices subordinate to people is wrong.   The
+> problem space has offices associated with zero or more people, and
+> people associated with zero or more offices.  Any program structure that
+> doesn't reflect this is going to be subject to major restructuring
+> during development and maintenance.
+
+I agree with you for the textbook example of offices and people.  However in
+real life there are roughly a dozen layers of software between classes that
+represent real-life entities like offices and people, and classes that
+interface with software infrastructure like databases, UI, network or OS.
+As you go down these layers, the decisions because harder and harder to make
+and may have to change over time.
+
+One common reason for change is performance: you may have to add a cache
+somewhere, or to keep an extra pointer on the last accessed object, etc.
+That can easily add circularities.
+
+I ran into a situation like that in C++ a while ago, in the code of our Ada
+editor.  I had two classes C1 and C2, and it was clear from day one that
+they were dependent on each other.  C1 had a component of type C2 and C2 had
+a component of type C1*.  I won't go into the details, but they were part of
+a data structure implemented using a doubly-linked list.  Because of
+performance problems I decided to change the data structure to use a skip
+list.  To do this I had to change the classes so that C1 had a component of
+type C2* and C2 had a component of type C1.  In C++ this was very easy to
+do, and, because the classes were designed with the proper level of privacy,
+the clients were entirely unaffected (although the implementation of C1 and
+C2 had to be completely rewritten).
+
+My point is that this is exactly a maintenance change, it's not that the
+design was fundamentally broken.  And it was really easy to do in C++...
+
+PS: One could argue that I could have pointers in both classes and be done
+with it.  But I try to avoid dynamic allocation if possible.  And of course
+pointers create the risk of unwanted sharing, i.e. more bugs.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, January 24, 2003  4:01 AM
+
+Tuck commented:
+
+> I also wonder how common it will be to consider introducing a circular
+> dependence a typical "maintenance" activity.  Circular type dependence
+> almost always implies some kind of recursive processing as well, so this
+> doesn't seem like a "small" change.
+
+Of course this discussion is similar to "I wonder how many people will be
+impacted if we introduce this incompatibility".  The truth is we don't know
+and we have no way to know.  In general however I think it's bad language
+design to force users to follow a certain pattern if there is no compelling
+reason to do so.
+
+Also note that circular dependences are not restricted to data structures:
+you may introduce a circular dependence because (in my example) you add in
+P2 an operation that takes parameters of type T1 and T2 (assuming that the
+types are tagged).
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, January 24, 2003  4:19 AM
+
+Jean-Pierre noticed:
+
+> There is no circular dependency problem if all packages are nested within
+one big package.
+> The only new possibility of this solution is to separate (part of) the
+specification.
+> Separating the body was of course already possible.
+
+Good point.  Actually, for tagged types, there is no circularity problem if
+you are willing to play games with access-to-class-wide types:
+
+    package Root is
+    private
+        type Type_1 is abstract tagged null record;
+        type Access_Type_1_Class is access Type_1'Class;
+        -- Similarly Type_2, Type_3, etc.
+    end Root;
+
+Now put all your code in children of Root, derive all your types from some
+Type_n and use Access_Type_n_Class whenever you have to create circular
+dependences.
+
+This is starting to look pretty much like package prefixes to me.  I realize
+that there are differences, but the two approaches share some of the same
+drawbacks.  If we are to design a brand new language feature, maybe it
+should have clear advantages over what can already be done with Ada 95.
+
+Pascal
+
+PS: Of course, in Ada 95 there is not much you can do in the case of
+untagged types.
+
+*************************************************************
+
+From: Robert A. Duff
+Sent: Friday, January 24, 2003  7:18 AM
+
+> Now put all your code in children of Root, derive all your types from some
+> Type_n and use Access_Type_n_Class whenever you have to create circular
+> dependences.
+
+But then you have zillions of downward conversions scattered all over
+the code.
+
+> This is starting to look pretty much like package prefixes to me.  I realize
+> that there are differences, but the two approaches share some of the same
+> drawbacks.  If we are to design a brand new language feature, maybe it
+> should have clear advantages over what can already be done with Ada 95.
+
+By the way, my initial idea for solving the circular dependence problem
+was based on this trick.  Add a way to declare "this abstract type has
+only one type derived from it".  Check at link time.  And then make
+downward conversions implicit -- it's safe, because you know the tag
+must be correct.  So yes, the tagged type trick is related to package
+prefixes.
+
+> Pascal
+>
+> PS: Of course, in Ada 95 there is not much you can do in the case of
+> untagged types.
+
+You can do the same sort of trick for untagged types, if you're willing
+to use unchecked conversions all over.  Yuck.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Friday, January 24, 2003  8:05 AM
+
+Jean-Pierre noticed:
+
+>There is no circular dependency problem if all packages are nested within
+>one big package. The only new possibility of this solution is to separate
+>(part of) the specification.
+
+Yes, that is exactly what we are accomplishing.
+And that is all that is really needed.  And note
+that in general only *one* package needs to have
+a little bit be physically nested, and that is
+enough to allow all the others to be completely
+separately compiled children.
+
+>>Separating the body was of course already possible.
+
+Right, but that still meant that the package spec was
+huge, and growing without bound.  With having just
+a nested "prefix," we only need to nest one (or a very
+small number) of sub-package prefixes physically within the
+parent package.  So the parent package spec does not
+grow without bound as you add more sub-packages into
+the circularity.
+
+Pascal wrote:
+
+> This is starting to look pretty much like package prefixes to me.  I realize
+> that there are differences, but the two approaches share some of the same
+> drawbacks.  If we are to design a brand new language feature, maybe it
+> should have clear advantages over what can already be done with Ada 95.
+
+I don't see this.  Nesting a single package prefix could break circularity
+in many systems, without any additional, artificial, downward
+(or unchecked) conversions thrown in.
+
+That seems like a *clear* (huge? ;-) advantage over Ada 95.
+The fact that it is accomplished with such a modest change
+to the syntax and semantics seems like a feature, not a bug.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, January 24, 2003  8:05 AM
+
+>My point is that this is exactly a maintenance change, it's not that the
+>design was fundamentally broken.  And it was really easy to do in C++...
+>
+And it should be similarly easy in Ada, no question.  My point was that,
+when as in this case you have two types (classes) C1 and C2 that are of
+equal precedence the program structure has to reflect that fact, or you
+run into implementation and maintenace difficulties.  If  you make it
+visible at a design, not an implementation level that C2 is a component
+of C1, then your maintenance change requires changing the design.
+
+If the design treats the classes as of equal precedence, however, the
+change you made would occur only (in Ada) in the private parts and
+bodies and bodies of the packages that exported the two abstractions.
+ This is the real problem that we are trying to address.  Right now Ada
+forces you to choose an asymmetric design, and at least 50% of the time,
+that design will be wrong.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Friday, January 24, 2003  7:51 PM
+
+> Now put all your code in children of Root, derive all your types from some
+> Type_n and use Access_Type_n_Class whenever you have to create circular
+> dependences.
+
+And this is fairly close to what we did in Claw. The difference being that
+we made the root types visible and added some of the root operations (such
+as destruction) at this level. That cut down the number of explicit
+conversions needed dramtically, but at the cost of putting a lot of code in
+the root.
+
+For CBuild, I simply used names rather than links (in part because there is
+no common parent to use), but that has some problems as noted.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Friday, January 24, 2003  8:15 PM
+
+Tucker said:
+
+> That seems like a *clear* (huge? ;-) advantage over Ada 95.
+> The fact that it is accomplished with such a modest change
+> to the syntax and semantics seems like a feature, not a bug.
+
+Please stop claiming this is a "modest" change without proof. I remain
+skeptical, after all "type stubs" were very simple (but ended up with a
+bunch of strange availability rules). And the impact on elaboration and
+freezing and visibility remains to understood.
+
+You're going to have to show me the wording before I can sign up for any
+change to visibility. And even if not a word of visibility needs to change
+(which I sincerely doubt), it is going to be a significant change inside of
+compilers. It might be easier to add a third part than adding the second,
+but I doubt it will be very much easier.
+
+*************************************************************
+
+From: Ed Schonberg
+Sent: Sunday, January 26, 2003  8:11 AM
+
+The simplest way to avoid freezing and elaboration issues is to restrict
+the contents of the "child package abstract" (does this have a name yet?)
+to contain only incomplete type declarations and access type declarations.
+This is what is needed to solve the circular dependence problem. Anything
+else can only be a can of worms. I concur with Randy that anything that
+touches on visibility is a major disruption to compilers, not a neat bounded
+change. Only a minimalist solution has a chance here.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Sunday, January 26, 2003  10:20 AM
+
+Randy writes, and Ed reiterates:
+
+>  Please stop claiming this is a "modest" change without proof.
+
+Here is not a proof, but perhaps a way of looking at it
+that might make it seem modest (or at least less frightening).
+The idea is to make the child into a "normal" nested package,
+and put its body into a subunit.  Now create a stub in
+the middle of its body, and think of the code preceding
+the stub as the rest of the spec of the child, and
+the code following the stub as the "true" body of
+the child.  This situation should approximate the visibility
+and freezing rules that would be associated with
+this proposal.
+
+For example, imagine the following, which is almost legal in
+Ada 95.  [The thing that is not legal is that we have allowed
+the deferred incomplete type to be in the visible part
+of C.  This might be a reasonable relaxation of the rules
+anyway, though that is a separate (but related!)
+topic for conversation... ;-)]:
+
+package P is
+    ...
+    package C is
+       -- this is like the "prefix" of the spec of C
+        type Some_Enum is (Red, Green, Blue);
+        type T(E : Some_Enum);  -- deferred incomplete type
+
+        type T_Ptr is access all T;
+        for T_Ptr'Storage_Pool use ...;
+
+        function Whatever return T_Ptr;
+    end C;
+    ...
+end P;  -- freezing happens no later than here
+         -- for anything declared in "prefix" of C
+
+package body P is
+    package body C is separate;
+    ...
+end P;
+
+separate(P)
+package body C is
+    -- This is like the "main" part of the spec of C
+    type T(E : Some_Enum) is record
+        X : Integer;
+    end record;
+
+    procedure Op1(Y : in out T);
+    procedure Op2(Z : in T);
+
+    package Viewpoint is end;
+    package body Viewpoint is separate;  -- Freezing happens here for
+                                         -- "main" part of spec of C
+
+    -- And here starts the "body" of C.
+
+    function Whatever return T_Ptr is ...
+    procedure Op1(Y : in out T) is ...
+    procedure Op2(Z : in T) is ...
+    ...
+end C;
+
+
+separate(P.C)
+package body Viewpoint is
+    -- What is (directly) visible here from P.C is what will be
+    -- (selectively) visible here in units that "with" P.C.
+    ...
+end Viewpoint;
+
+As you can see, we have partitioned P.C into three parts,
+the first part physically nested in the spec of P (the "prefix"),
+the second part preceding an external viewpoint (the "main" part
+of the spec), and the third part following the external
+viewpoint (the "body").
+
+--------
+
+And now for that other conversation -- allowing a deferred
+incomplete type to be in the visible part seems a reasonable
+relaxation in general, since all of these type-stub/package abstract/
+package prefix are making uncompleted incomplete types more widely visible.
+They were already visible to child packages in Ada 95, so it
+probably doesn't represent an implementation burden.
+I suppose the only problem is that it might be simply
+a "bug" that the user forgot to complete the incomplete type.
+But it is a bug that will be caught when the body is compiled,
+so that seems pretty reasonable.
+
+Another similar relaxation that many customers and non-paying
+users alike have wished for has been the ability to complete
+a deferred constant in a package body.  This is "standard fare"
+in C and C++, and is extremely useful from a separate compilation
+point of view.   Again, this might mask a bug where the user
+simply forgot to complete the constant, but it would be caught
+as soon as the body is compiled.
+
+In any case, it seems we certainly want to allow such things
+in package abstracts/prefixes (if we go that route), since we
+know the abstract/prefix represents only part of the spec.
+But it seems that once you go that far, you might as well
+grant the added flexibility to users of more "mundane"
+package specs and bodies.
+
+*************************************************************
+
+From: Dan Eilers
+Sent: Tuesday, January 28, 2003  2:52 PM
+
+It looks to me like we can combine the "type stub" proposal with
+Tucker's "child prefix" proposal, and get the best of both worlds,
+without the negatives of either.
+
+The big negative of "type stub" is that the type stub names a unit
+that isn't previously declared.
+
+The big negative of "child prefix" is that it impacts client code
+by changing all type references from P.T to P.child.T.  Only the
+clients that need the full type (e.g. for declaring objects) should
+have to say P.child.T.
+
+The "prefix" proposal addresses the first negative by:
+  1) restricting the full type to be in a child unit
+  2) giving a "forward" declaration of the child in its parent.
+
+By requiring the full type to be in a child unit, there
+is also no complexity associated with the case where the
+child could be with'd but not the parent.
+
+The "type stub" proposal addresses the second negative by
+declaring the type stub directly within the parent.
+
+So if we combine the two proposals, we get:
+
+package P is
+    package C;    -- or whatever syntax we like for a child unit stub
+    type T is separate in C;
+    type T_Ptr is access T;
+end P;
+
+
+instead of:
+
+-- type stub proposal
+package P is
+    type T is separate in P.C;
+    type T_Ptr is access T;
+end P;
+
+or:
+
+-- child prefix proposal
+package P is
+    package C is separate
+        type T;
+        type T_Ptr is access T;
+    end C;
+end P;
+
+
+Note: I am somewhat reluctant to propose using the keyword "separate"
+in a child unit stub, since "separate" generally implies that the stub
+can't be with'd.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, January 28, 2003  2:53 PM
+
+Unfortunately this doesn't address the problem
+where all types are called "Object" and the package
+name is effectively part of the type name.
+This was considered a common enough idiom at SIGAda 2002
+that I really think we need to solve it.
+
+I think a structural advantage to the child prefix proposal as is
+is that it tends to lead to all the packages that participate
+in a circular dependence being in the same subsystem, rather
+than just a random collection of root packages.
+
+Since it is relatively painless to add a layer to move a set
+of related packages into a subsystem, this seems like
+a small price to pay to allow circular dependence.  The only
+changes are in "with" clauses, and perhaps a "use" for
+the subsystem as a whole.  Renames can also be used to
+make the packages visible with their old library name.
+
+Note that we inserted the "Ada" layer into the Ada 83 run-time
+library, with no significant upward incompatibilities, thanks
+to library-unit renaming.
+
+*************************************************************
+
+From: Dan Eilers
+Sent: Tuesday, January 28, 2003  5:24 PM
+
+Tucker wrote:
+> Unfortunately this doesn't address the problem
+> where all types are called "Object" and the package
+> name is effectively part of the type name.
+> This was considered a common enough idiom at SIGAda 2002
+> that I really think we need to solve it.
+
+OK, I worked out an example which makes this more clear.
+
+Given the canonical example of Employees and Departments
+expressed using the original "package abstracts" of AI-10217:
+
+    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;
+    end Employees;
+
+    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);
+    end Departments;
+
+
+This would be expressed in my proposed hybrid type-stub/prefix form as:
+
+    package Employees is
+        package Extension;             -- new child package stub
+        type Employee is separate in Extension;
+        type Emp_Ptr is access all Employee;
+    end Employees;
+
+    package Departments is
+        package Extension;             -- new child package stub
+        type Department is separate in Extension;
+        type Dept_Ptr is access all Department;
+    end Departments;
+
+    with Departments;
+    package Employees.Extension is
+        type Employee is private;
+        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
+           dept: Departments.Dept_Ptr;
+        end record;
+    end Employees.Extension;
+
+    with Employees;
+    package Departments.Extension is
+        type Department is private;
+        procedure Choose_Manager(D : access Department;
+                                 Manager : access Employees.Employee);
+    private
+        type Department is
+           emp: Employees.Emp_Ptr;
+        end record;
+    end Departments.Extension;
+
+
+A user would probably want to use library-level renaming to avoid having
+to refer to the Extension child unit in the clients.
+
+Calling everything "Object" works fine, resulting in:
+
+    package Employees is
+        package Extension;             -- new child package stub
+        type Object is separate in Extension;
+        type Emp_Ptr is access all Object;
+    end Employees;
+
+    package Departments is
+        package Extension;             -- new child package stub
+        type Object is separate in Extension;
+        type Dept_Ptr is access all Object;
+    end Departments;
+
+    with Departments;
+    package Employees.Extension is
+        type Object is private;
+        procedure Assign_Employee(E : access Object;
+                                  D : access Departments.Object);
+        function Current_Department(D : access constant Object) return
+            Departments.Dept_Ptr;
+    private
+        type Object is record
+           dept: Departments.Dept_Ptr;
+        end record;
+    end Employees.Extension;
+
+    with Employees;
+    package Departments.Extension is
+        type Object is private;
+        procedure Choose_Manager(D : access Object;
+                                 Manager : access Employees.Object);
+    private
+        type Object is
+           emp: Employees.Emp_Ptr;
+        end record;
+    end Departments.Extension;
+
+
+Reorganizing to use a new root package Directory, we would get:
+
+    package Directory is
+        package Employees;       -- new child package stub
+        type Employee is separate in Employees;
+        type Emp_Ptr is access all Employee;
+        package Departments;     -- new child package stub
+        type Department is separate in Departments;
+        type Dept_Ptr is access all Department;
+    end Directory;
+
+    package Directory.Employees is
+        type Employee is private;
+        procedure Assign_Employee(E : access Employee;
+                                  D : access Directory.Department);
+        function Current_Department(D : access constant Employee) return
+            Directory.Dept_Ptr;
+    private
+        type Employee is record
+           dept: Directory.Dept_Ptr;
+        end record;
+    end Directory.Employees;
+
+    package Directory.Departments is
+        type Department is private;
+        procedure Choose_Manager(D : access Department;
+                                 Manager : access Directory.Employee);
+    private
+        type Department is
+           emp: Directory.Emp_Ptr;
+        end record;
+    end Directory.Departments;
+
+which also works fine, except that as you point out, it doesn't allow
+type Employee and Department to both be named Object.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 29, 2003  8:55 AM
+
+Here is another step toward simplification,
+inspired in part by Dan Eiler's recent thoughts.
+It also happens to be very similar to a proposal
+consided during the Ada 9X process, with the crucial
+difference that it would be allowed in the visible part.
+
+Basically, the propsal is to allow an incomplete type declaration to
+use a (singly) "dotted" name for the type being introduced:
+
+E.g.:
+
+package P is
+
+     type C.T;  -- incomplete type, specifying that
+                -- full type will be in a nested or child
+                -- package.
+
+     type T_Ptr is access C.T;  -- if desired
+
+      ...
+
+end;
+
+package P.C is
+    type T is ...  -- full type
+
+    subtype T_Ptr is P.T_Ptr;  -- if desired
+
+    ...
+
+end P.C;
+
+---------------
+
+That's it, except of course we all seem to agree that the
+tagged incomplete type is a good idea, and that incomplete
+types should be allowed to be completed by a private type.
+
+The major change relative to the child package prefix proposal
+is that we have eliminated the new kind of program unit.
+
+How does this compare with other proposals?
+
+"with type" had the following problems:
+1) New kind of "with" clause
+2) Dependence that isn't really a dependence
+3) with-type clause could appear anywhere, making
+    it difficult to know when to check that the
+    full type existed and matched the with-type.
+
+"package abstracts" had the following problems:
+1) Required a new kind of program unit and with clause
+2) Special rules for elaboration order and corresponding
+    restrictions on what could appear in the abstract, including
+    possibly nested abstracts, etc.
+3) Unclear rules about what part of the parent unit the
+    abstract of a child got to see (none, abstract only,
+    full spec).
+4) Because a package abstract is optional, it has some
+    of the same headaches associated with optional
+    specs on library unit subprograms.
+
+"type stubs" had the following problems:
+1) Multiple type stubs for the same type makes it
+    unclear exactly when the check is to be performed
+    that the package completes the type stub.
+2) Trouble when all types have the same name (e.g. Object).
+3) Lack of mention in a context clause of the enclosing package,
+    leading to a new kind of with clause, leading to a new
+    kind of dependence
+4) Type stub and full type didn't have the same fully expanded
+    name, making for tricky rules for when and where the name
+    associated with the type stub could be used to represent
+    the full type.  Subtle "availability" rules.
+
+
+"child package prefixes" had the following problems:
+1) Syntax suggests that feature would make sense for
+    root packages, but a seemingly "arbitrary" restriction
+    only allows prefixes for child (or nested) packages.
+
+
+---------------
+
+This proposal does not have any of the above problems, though
+of course it does have some problems.  Here are some
+of the problems, with some of the remediating factors:
+
+1) It restricts this new capability to types that are in child
+    or nested packages.
+
+Remediating factor: Since types are not separately compilable,
+it creates less of an expectation that the feature should work
+for types in root packages.  Furthermore, it is unlikely the
+user will think of it that way.  Rather, the way it reads to a user
+is that in the past, I could use incomplete types to create
+mutually recursive types in a single package.  Now I can use
+these new more flexible incomplete type declarations to create
+mutually recursive types that involve a package and its child
+or nested packages.
+
+2) It introduces the name of a child/nested package as part of
+    an incomplete type declaration, leading to a "ghost" package
+    (as Pascal has called it).
+
+Remdiating factor: This ghost package exists only in the scope
+where it will ultimately appear for real as a nested or
+child package, rather than having to be constructed at each
+"with-type" clause.  One of the problems with the ghost packages
+required by the with-type clause was that different units might
+have different sets of with-type clauses, so this ghost package might
+have more or fewer incomplete types declared inside it, depending on
+the number of with-type clauses in scope.  And then if you "with"
+the "real" package, it somehow has to be merged with and/or checked
+against the various ghost packages.  In this proposal, the ghost
+package is created at the first such incomplete type declaration,
+and only can grow if there are more incomplete type declarations
+appearing in the enclosing package spec.  There is never more than
+one "ghost" package for a given nested/child package, and every
+one sees the "same" ghost package.
+
+3) There is no way to "pre"-declare an access type that ends up
+    inside the nested/child package.
+
+Remediating factor: You can declare the access type in the enclosing
+package, and then use a subtype or derived type declaration to put
+an equivalent/interconvertible access (sub)type into the nested/child
+package, if desired.
+
+As usual, fire away...
+
+*************************************************************
+
+From: Arnaud Charlet
+Sent: Wednesday, January 29, 2003  9:11 AM
+
+This last proposal has definitely many interesting capabilities and
+addresses several issues.
+
+However, I don't think (or at least I don't see how) it addresses the issue
+of generating "bindings" to API written in existing languages.
+
+Suppose you have e.g. two header files, or two java classes, not under
+the same hierarchy, with type definitions referencing one another. How would
+you automatically and "naturally" translate these with your proposal ?
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, January 29, 2003  9:46 AM
+
+That certainly seems like an appropriate criterion. Certainly we want a
+solution that works at least as well in this regard as the current
+version of WITH TYPE that we have implemented, and routinely use for
+this purpose.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, January 29, 2003  9:58 AM
+
+Agreed, and that's what makes me uncomfortable with the notion of tying
+incomplete types with child units.  In real life you have many constraints on
+how you organize your compilation units, and Tuck's proposals all add yet
+another contraint.  I fear that in a number of cases this extra constraint will
+make the set of solutions empty.
+
+*************************************************************
+
+From: Ed Schonberg
+Sent: Wednesday, January 29, 2003  10:08 AM
+
+But why is the incomplete declaration tied to a child unit?
+
+Tucker proposes:
+
+>   Basically, the propsal is to allow an incomplete type declaration to
+>   use a (singly) "dotted" name for the type being introduced:
+
+>   E.g.:
+
+>   package P is
+>
+>        type C.T;  -- incomplete type, specifying that
+>                   -- full type will be in a nested or child
+>                   -- package.
+
+I don't see why a child ghost is preferable to an arbitrary ghost! The
+declaration introduces the name of a unit that will eventually be
+compiled and provide the completion for the type. Why the restriction to
+a member of the family?
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, January 29, 2003  10:08 AM
+
+> That's it, except of course we all seem to agree that the
+> tagged incomplete type is a good idea, and that incomplete
+> types should be allowed to be completed by a private type.
+
+Tagged incomplete types are certainly a good idea.
+
+Completing an incomplete type by a private is an appealing idea from a language
+design standpoint, but it frightens the implementer in me.  In essence, I fear
+that having three-part types is going to break a lot of invariants in
+implementations.  We have a zillion places in our compiler where we do a very
+complex analysis to decide what we know about a type at a particular place
+(i.e., whether we see the partial view or the full view) and I cannot believe
+that other compilers don't have similar contraptions.  Changing this to deal
+with three-part-types is going to be a lot of work.
+
+Ideally I would love to merge the partial view and the incomplete view (and
+stick to two-part types), but I have not been able to come up with sensible
+ideas on how to do that.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 29, 2003 10:31 AM
+
+Ed Schonberg wrote:
+> Pascal writes:
+>
+>> Agreed, and that's what makes me uncomfortable with the notion of tying
+>> incomplete types with child units.  In real life you have many constraints on
+>> how you organize your compilation units, and Tuck's proposals all add yet
+>> another contraint.I fear that in a number of cases this extra constraint will
+>> make the set of solutions empty.
+
+I have suggested that it is always relatively "easy" to introduce
+an extra layer at the "top" of a (sub)system, as indicated
+by our introduction of "Ada." in Ada 9x.  Can you give some
+examples where this is not so easy, so I can appreciate the
+issue better?
+
+> But why is the incomplete declaration tied to a child unit?
+>...
+>
+> I don't see why a child ghost is preferable to an arbitrary ghost! The
+> declaration introduces the name of a unit that will eventually be
+> compiled and provide the completion for the type. Why the restriction to
+> a member of the family?
+
+Because having multiple ghosts for the same package creates
+significantly more problems, and the "completing" package
+is unaware of the existence of these ghosts, and hence
+checking of appropriate completions has to be performed
+by users of the type, rather than by the declarer of the
+type.
+
+Both of the proposals I have made recently eliminate any
+special work on the part of the users of such an incomplete
+type.  All of the work is localized to the place where the
+type is completed, since it is guaranteed to see and be
+aware of the incomplete type declaration.
+
+*************************************************************
+
+From: Arnaud Charlet
+Sent: Wednesday, January 29, 2003 10:44 AM
+
+> I have suggested that it is always relatively "easy" to introduce
+> an extra layer at the "top" of a (sub)system, as indicated
+> by our introduction of "Ada." in Ada 9x.  Can you give some
+> examples where this is not so easy, so I can appreciate the
+> issue better?
+
+I don't think an automated tool that would take e.g. existing C or Java
+headers would be able to easily introduce an extra layer and put every
+needed circular dependence in the parent package. This would require a
+global processing of all possible units, and would mean having to regenerate
+everything each time a new unit is added. It would also mean lots of
+unrelated declarations in the parent package.
+
+Unless I am missing something, this is definitely not a very attractive
+solution if you take the foreign language bindings into account.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 29, 2003 11:06 AM
+
+Robert Dewar wrote:
+ >>Suppose you have e.g. two header files, or two java classes, not under
+ >>the same hierarchy, with type definitions referencing one another. How would
+ >>you automatically and "naturally" translate these with your proposal ?
+ >
+ >
+ > That certainly seems like an appropriate criterion. Certainly we want a
+ > solution that works at least as well in this regard as the current
+ > version of WITH TYPE that we have implemented, and routinely use for
+ > this purpose.
+
+I agree that "with type" is the simplest for binding generators,
+but we have seen the various technical problems associated
+with this proposal, when we try to nail down full
+implementation-independent semantics for it.
+
+As I mentioned in an earlier note, I personally now prefer "with type"
+(for incomplete types only, not for access types) to type
+stubs and package abstracts, but there is still the somewhat
+tricky rules required having to do with who checks that
+the full type exists and matches the with-type (i.e. is tagged
+if specified), and the issue of multiple distinct package
+"ghosts" that have to be correlated.
+
+In any case, I believe that a binding generator for Java
+could relatively easily add the appropriate incomplete type declarations
+(required by this newest proposal) into the enclosing package when
+necessary.  Certainly in Java it is absolutely standard practice to put
+every class of any importance in an enclosing package, so there would
+always be a place to "drop" these incomplete type declarations
+in the generated Ada.  It might be a bit of an "art" to
+put as few incomplete type declarations as possible in the
+enclosing package, but that is more of an optimization than
+a requirement.
+
+For C, it would probably be natural (or at least not unnatural)
+to create a binding which involved multiple C header files as a
+package hierarchy, with a root package where these incomplete type
+declarations could be dropped as needed.  In C++, namespaces
+correspond to Java's classes, and it is becoming more common to
+declare C++ classes in namespaces, so again, the package representing
+the namespace would be a natural place to declare the
+incomplte types for "<classname>.Object" or whatever naming
+convention is used for C++ classes.
+
+Note that in C and C++, it is probably more "obvious" than
+in Java when an incomplete type declaration is needed, since
+C/C++ have a corresponding notion of incomplete type references.
+A type from another header that is referenced with such an
+incomplete type reference would be an obvious candidate to
+be have an Ada incomplete type declaration for it placed in
+the enclosing package.
+
+I don't think it is a bad tradeoff to make binding generators
+a bit more complicated (or perhaps even require a small amount
+of manual fixup) to keeping the language and the compilers
+simpler.
+
+For me, at least, my two favorite proposals are now "with type"
+(for incomplete types only) and this newest one.  They both
+have the nice effect that there is exactly one fully expanded
+name for the type, so those using types all called "Object"
+or whatever have no problems.  Also, we don't have to specify
+complex rules about when one name means the same thing as
+some other name for the "same" type.
+
+This newest proposal has the added benefit that there is at most
+one incomplete type for a given complete type, rather than one
+created for each "with type."  Furthermore, the complete type
+knows that the incomplete type is visible to other units, in
+as much as that might affect representation of pointers (given
+the possibility of pointer type conversion).
+Admittedly, it makes binding generators more complicated, but
+I believe it simplifies implementations, and avoids introducing
+a new kind of context clause or a new kind of unit dependence.
+
+*************************************************************
+
+From: Dan Eilers
+Sent: Wednesday, January 29, 2003 12:08 PM
+
+Arno wrote:
+> However, I don't think (or at least I don't see how) it addresses the issue
+> of generating "bindings" to API written in existing languages.
+>
+> Suppose you have e.g. two header files, or two java classes, not under
+> the same hierarchy, with type definitions referencing one another. How would
+> you automatically and "naturally" translate these with your proposal ?
+
+You would basically have two choices:
+
+1) invent a parent to hold the type stubs; or
+2) split the package into two parts, one part being the parent of the other,
+   with the type stubs in the parent, and use a library-level renames to
+   rename the child to what you want the clients to use.
+
+
+Robert Dewar wrote:
+> That certainly seems like an appropriate criterion. Certainly we want a
+> solution that works at least as well in this regard as the current
+> version of WITH TYPE that we have implemented, and routinely use for
+> this purpose.
+
+Well, the nicest solution for the user is just to allow specs to with
+each other, as other languages do.  With type is the second nicest
+user solution, but was abandoned a long time ago for a number of reasons
+(see Randy's enumeration).  Separately compiled package abstracts are
+the third nicest user solution, but they have tool impact due to a
+new kind of compilation unit.  That leaves putting the abstract either
+in a parent, or in a child, or in an unrelated unit.
+
+Putting the abstract in an unrelated unit prevents having to invent
+a parent, but was rejected by users at the SigAda meeting, for violating
+the rule that you can't normally refer to an undeclared unit.
+
+Putting the abstract in a child unit also prevents having to invent
+a parent, but violates the rule that you can't normally compile a child
+unit before compiling its parent.
+
+Putting the abstract in a parent unit is the current proposal.  It is
+probably the least convenient for the user of the proposed solutions,
+since a parent generally has to be invented or the child renamed, but
+it is the most consistent with Ada's general design principles.
+
+Ed Schonberg wrote:
+> I don't see why a child ghost is preferable to an arbitrary ghost!
+
+Because it is consistent with the Ada design principle that child units
+are the mechanism for package extension.
+
+*************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, January 29, 2003 12:37 PM
+
+Since we are furiously inventing...
+
+(I thought I submitted this before, but since nobody reacted, it must have been
+lost - or is it that stupid that nobody even cared to respond? :-).
+
+Taking back the package abstract idea, but as a context clause:
+
+with package Foo is
+   type T;
+end Foo;
+package Bar is....
+
+i.e. each user of a package abstract must repeat it as a context clause,
+therefore avoiding the new compilation unit issue.
+
+There would be a burden at link time, since it is necessary to check that the
+actual Foo fulfills the promises of all package abstracts.
+
+Note that different packages may choose different abstracts from Foo (if it
+provides several types f.e.) which may not be a bad thing. I.e. each unit makes
+its own abstract of a complex package, importing only what's needed.
+
+No restriction to child unit, so it would address the concern of Java specs.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 29, 2003  2:02 PM
+
+> package P is
+>
+>      type C.T;  -- incomplete type, specifying that
+>                 -- full type will be in a nested or child
+>                 -- package.
+>
+>      type T_Ptr is access C.T;  -- if desired
+>
+>       ...
+>
+> end;
+
+I dislike this syntax, for the simple reason that it requires a change to
+Type_Declaration, rather than to Type_Definition. That ups the ante for
+implementation considerably (Janus/Ada at least, processes those two
+productions separately). Let me suggest another syntax:
+
+     type T is separate in C;
+
+:-)
+
+This immediately shows us that this is type stubs with restriction on the
+stub package; nothing more and nothing less.
+
+(Indeed, this is slightly better than Tucker's proposal, because there are
+no ghost packages.)
+
+The restriction seems to buy us two things:
+
+    1) Since the completion has to (by definition) see the stub, the
+       completion rules are substantially simplified. (Perhaps to
+       non-existent.)
+    2) Since the completion has to be in the child package, and child
+       packages already can appear without any notation in their parent,
+       we've defined away the dependence in the context clause concern.
+       (I doubt that will really make the people who complained happy,
+       but that's the solution.)
+
+Of course, it also continues to have the problem of forcing a design into
+child packages whether that is desired or not.
+
+We could get the advantages of (1) and not have the requirement to force the
+design, by requiring that the completion with the package containing the
+stub. That would have to be a post-compilation rule (unfortunately), but it
+would eliminate virtually all of the completion complexity. [While it would
+be possible for packages with different visibility on the stub to meet,
+since withs are non-transitive, we know that withs are transitive for the
+purposes of type matching. Thus, anything with visibility on the completion
+would have "know" about the stub, so type compatibility would remain as it
+currently is in implementations (such as a compare of type numbers in
+Janus/Ada).]
+
+Of course, that does not do anything to address the user concern about
+showing dependence in the context clause. That could be addressed as in
+alternative #5, or we could declare it a red herring and move on (as some
+people here seem to prefer to do).
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 29, 2003  2:10 PM
+
+> That certainly seems like an appropriate criterion. Certainly we want a
+> solution that works at least as well in this regard as the current
+> version of WITH TYPE that we have implemented, and routinely use for
+> this purpose.
+
+But it's also an impossible criterion. I don't think that any of the
+proposals considered (INCLUDING with type) meets it. That's because the GNAT
+with type allows withs of access types, which we had to eliminate from any
+proposal because of various problems. And I expect that would be the
+keystone to any "easy" importation of Java or C++ classes.
+
+Therefore, with ANY proposal that the ARG has considered requires the
+introduction of a second package - either an abstract (or prefix), or a real
+package containing a type stub (which includes Tucker's most recent "parent"
+proposal).
+
+And thus, the translator of the classes is going to have to do some
+restructuring.
+
+In any case, I think it is important that we not lose sight of the fact that
+whatever we choose needs to be natural in an all-Ada design. Ada programmers
+have had this problem for 20 years, and generally have had to bloat up
+packages to deal with it. It would be pretty silly to adopt something simply
+because it makes copying Java classes easy (unless we believe that there
+won't be any new Ada designs -- in which case, we're all wasting our time on
+this whole exercise).
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 29, 2003  3:10 PM
+
+> I dislike this syntax, for the simple reason that it requires a change to
+> Type_Declaration, rather than to Type_Definition.
+
+Is this really that big a deal?  Compared to all the other options?
+
+> ... That ups the ante for
+> implementation considerably (Janus/Ada at least, processes those two
+> productions separately).  Let me suggest another syntax:
+>
+>      type T is separate in C;
+>
+> :-)
+
+But what does this mean?  Is the full name for the type "P.C.T" or is it "P.T"?
+The fact that I have to ask this question makes me think it is an error prone
+syntax.
+
+> This immediately shows us that this is type stubs with restriction on the
+> stub package; nothing more and nothing less.
+>
+> (Indeed, this is slightly better than Tucker's proposal, because there are
+> no ghost packages.)
+
+I have lost you.  Don't you still have to create "C", or are you saying
+the full name of the type is "P.T"?  If the latter, then you are
+back to the situation where, presumably, in some cases P.T is an
+incomplete type, and in other somewhat-difficult-to-define cases,
+P.T is a "complete" type.  Or are you saying that P.T is *always* an
+incomplete type, even if you "with" P.C?
+
+To me it is this issue of when or if "P.T" is a complete type that
+is the fundamental problem with type stubs which introduce their
+own name.
+
+> The restriction seems to buy us two things:
+>
+>     1) Since the completion has to (by definition) see the stub, the
+>        completion rules are substantially simplified. (Perhaps to non-existent.)
+>     2) Since the completion has to be in the child package, and child packages
+>        already can appear without any notation in their parent, we've defined away
+>        the dependence in the context clause concern. (I doubt that will
+>        really make the people who complained happy, but that's the solution.)
+
+I presume you are agreeing that the "type C.T;" proposal has the same
+two advantages.
+
+> Of course, it also continues to have the problem of forcing a design into
+> child packages whether that is desired or not.
+>
+> We could get the advantages of (1) and not have the requirement to force the
+> design, by requiring that the completion with the package containing the
+> stub.
+
+This sentence no verb. ;-)
+
+> ... That would have to be a post-compilation rule (unfortunately), but it
+> would eliminate virtually all of the completion complexity. [While it would
+> be possible for packages with different visibility on the stub to meet,
+> since withs are non-transitive, we know that withs are transitive for the
+> purposes of type matching. Thus, anything with visibility on the completion
+> would have "know" about the stub, so type compatibility would remain as it
+> currently is in implementations (such as a compare of type numbers in
+> Janus/Ada).]
+
+Unfortunately, I cannot understand this idea presumably due to lack
+of some key words in the sentences.
+
+> Of course, that does not do anything to address the user concern about
+> showing dependence in the context clause. That could be addressed as in
+> alternative #5, or we could declare it a red herring and move on (as some
+> people here seem to prefer to do).
+
+What is alternative #5, in a few words?
+
+Other than the detailed syntax, are you saying you like the semantics
+of "type C.T;", or are you saying you prefer the restricted-to-children
+type stub where the full name is "P.T;" of the incomplete type, while the
+complete type name is "P.C.T"?
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 29, 2003  4:21 PM
+
+> Unfortunately, I cannot understand this idea presumably due to lack
+> of some key words in the sentences.
+
+The only words that I saw that were missing was "is". I've been working on
+the search engine, where words like that are ignored, and I've taken it a
+bit too far... :-)
+
+Anyway, the basic idea is that P.T is always incomplete; P.C.T is complete
+and matches P.T trivially because it always knows about P.T. Thus the
+completion rules are simplified. (That does mean that P.T and Q.T don't
+match each other if both are stubs of the same completion; I don't think
+that matters in any of the canonical uses we've sketched out.)
+
+I definitely didn't work out the details on this one - one fully worked out
+alternative per meeting is my limit. :-)
+
+> > Of course, that does not do anything to address the user concern about
+> > showing dependence in the context clause. That could be addressed as in
+> > alternative #5, or we could declare it a red herring and move on (as some
+> > people here seem to prefer to do).
+>
+> What is alternative #5, in a few words?
+
+Some sort of context item to introduce a package name solely for use in type
+stubs. I had proposed
+    abstract of P;
+but the semantics are the same no matter what the syntax.
+    with separate P;
+works as well.
+
+> Other than the detailed syntax, are you saying you like the semantics
+> of "type C.T;", or are you saying you prefer the restricted-to-children
+> type stub where the full name is "P.T;" of the incomplete type, while the
+> complete type name is "P.C.T"?
+
+I think I like original type stubs the best. :-)
+
+I was just trying to figure out if your proposal was significantly different
+than type stubs, and it didn't seem like it.
+
+If I had to rank these by alternative number (and giving prefixes #6 and
+this latest one #7), I'd say:  4 (type stub alone), 5 (type stub with
+context marker), 7, 6, 1 (fixed up with type, any syntax).
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 30, 2003  8:32 AM
+
+There seems to be some feeling that type stubs
+were almost right, and we should either leave
+them as is, or add some kind of special context
+clause such as "separate with ..." and be done with it.
+
+Personally, I don't feel that way anymore.  Here are some
+reasons why:
+
+1) Type stubs look and feel like an add-on to the language.
+    Nothing about them looks natural to my eyes.  As a language
+    designer/enhancer, I always want the new features to look
+    like they were "always" there, so the language is seamless
+    and there is no obvious dividing line between old and
+    new features.
+
+2) Type stubs are not necessarily "seen" by the type completer.
+    I think this could have negative implications for compilers
+    like GNAT that have multiple representations for access types
+    (access-to-unconstrained array can be thick or thin, and I
+    presume there is no easy way to convert a thick pointer to a
+    thin one).  Of course GNAT itself doesn't have this particular
+    problem with their existing "with type" implementation, because
+    they "peak" at the actual type declaration at the time of
+    processing a "with type."  I suppose this same trick could
+    be used for type stubs, but requiring "peaking" at the
+    full type seems generally unwise, and has interesting
+    implications from a recompilation point of view.
+
+3) Type stubs seems to require a particular "idiom" of use
+    that makes it seem clear that some kind of package "prefix"
+    or "abstract" is what we *really* wanted but couldn't somehow
+    bring ourselves to provide.  To be specific, we
+    have said that to deal with cases where most types have
+    the same simple name (e.g. "Object"), you should use an
+    idiom where a separate package is created to hold the
+    type stub.  In fact, there seems to be some sense that this
+    is a good idiom even if the type names aren't all the same.
+    If this is really true, then it is clear to me that the
+    type stub feature we designed is not the right solution,
+    and a package prefix/abstract would be better.
+
+4) Type stubs have the unfortunate situation where the
+    same type has two different fully expanded names.  This
+    creates numerous problems and confusions for specifying the
+    rules, implementing the rules, and understanding the rules
+    relating to when the two types are the same and when they
+    are different. With the other approaches, there is only one
+    fully expanded name for the type, and the usual 8.3(19) hiding rule
+    that says a completion hides the prior declaration from all
+    visibility within its scope, will generally be adequate to
+    decide whether you have an incomplete type or a full type.
+
+--------------
+
+Of the other approaches that still seem viable to me,
+"with type," package prefix/abstract (including the
+stand-alone case), and "type C.T;" incomplete types:
+a) "with type" has odd dependency semantics (dependence
+    without a real dependence) and the completer doesn't
+    "see" the incomplete type(s)
+b) package prefix/abstract feels like a big change, requiring a new
+    kind of program unit, a new kind of context clause, and non
+    obvious rules about what part of the parent unit a child
+    prefix/abstract can see.  Admittedly, the package prefix is
+    probably the most powerful and flexible.
+c) "type C.T;" seems like a natural outgrowth of two basic facts:
+     i) the incomplete type declaration is the fundamental way
+        of supporting mutually dependent types in Ada, but it
+        is limited to only working within a single package spec;
+     ii) child packages are the fundamental way of splitting a large
+        abstraction into smaller, more manageable parts, but they are
+        limited in that mutually dependent types cannot cross
+        these pieces of the abstraction.
+
+Obviously the above analysis is biased by what feels to me
+to be the simplest "good" solution.  The major objection to
+the more flexible incomplete type declaration seems to be that
+it might not just "drop" into existing code.  But there is no
+existing code that actually solves the mutually dependent
+type problem.  There are only a collection of workarounds.
+It seems unwise to require that any "real" solution to the problem
+be able to simply drop easily into all existing workarounds.
+
+There is no rule that the existing workarounds have to overnight
+switch to using every new feature that might have obviated
+the workaround.  It is like in Ada 95 -- clearly tagged types are
+a nice solution to the problem of variant records and case
+statements growing larger and larger as a data abstraction
+gets more complex.  But to take advantage of tagged types,
+you really have to restructure everything.  So there are
+plenty of people still using variant records, for historical
+reasons, or because they are still waiting for the mutually
+dependent type problem to be solved before they "jump" to
+tagged types.  I don't think that means we should have designed
+tagged types so they could easily slip into all code that was
+using variant records before.
+
+We have to be focused on the person developing a new abstraction,
+and how the language can be enhanced in modest ways to
+enable that person to develop the abstraction without having
+to stand on their head.  The old abstractions that were built
+by standing on your head will probably always look like that,
+until there is the time and money to redesign them to take best
+advantage of new language capabilities.
+
+My final word is to try to answer "why the change of heart"?  Presenting
+the various Ada 200Y proposals to SIGAda '02 was generally a
+reconfirming experience, making me feel that we were generally
+on the right track.  However, the type stub proposal received
+more negative reaction than anything else.  This made me step
+back a bit from the proposal and try to look at it with the
+perspective of an outsider.  I concluded that this proposal
+seemed to be suffering from the results of "group think."
+
+Group think is where a relatively isolated group (e.g. the ARG)
+spends a very long time struggling to find a solution to a problem,
+and ultimately convinces themselves, perhaps out of exhaustion,
+that they have found the right solution.  But when someone new steps
+into the room, that new person immediately recognizes the solution
+for what it is -- a dog.  The group will generally try to pooh-pooh
+the outsider's view, feeling that they just don't understand all
+the complexities of the problem, or missed all the relevant discussions
+that went on arriving at the solution, and if the group is unlucky,
+they will ultimately dismiss the outsider's perspective.  I don't
+think we can afford to do that.  We really want the changes to
+Ada to stand the test of time, so years from now someone will
+look at Ada 200Y as a whole and think that it is a good, well integrated,
+internally consistent language, without a lot of ugly baggage
+hanging off the side due to periodic "maintenance" activities.
+
+Obviously, given our current resources, we don't want to waste
+implementors' or users' time with enhancements that won't stand
+the test of time, and have to be "re-maintained" many times
+in the future to get them right.  There were a few dogs in
+Ada 95 (like streams), and it has been painful to straighten
+them out.  Luckily, for most of these dogs, the core idea
+seems to have been good, even if the details were a shambles.
+
+Anyway, so much for philosophizing...
+
+*************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Thursday, January 30, 2003  10:06 AM
+
+> Group think is where a relatively isolated group (e.g. the ARG)
+> spends a very long time struggling to find a solution to a problem,
+> and ultimately convinces themselves, perhaps out of exhaustion,
+> that they have found the right solution.  But when someone new steps
+> into the room, that new person immediately recognizes the solution
+> for what it is -- a dog.  The group will generally try to pooh-pooh
+> the outsider's view, feeling that they just don't understand all
+> the complexities of the problem, or missed all the relevant discussions
+> that went on arriving at the solution, and if the group is unlucky,
+> they will ultimately dismiss the outsider's perspective.  I don't
+> think we can afford to do that.  We really want the changes to
+> Ada to stand the test of time, so years from now someone will
+> look at Ada 200Y as a whole and think that it is a good, well integrated,
+> internally consistent language, without a lot of ugly baggage
+> hanging off the side due to periodic "maintenance" activities.
+>
+Are you thinking of unreserved keywords here?
+
+(sorry, couldn't resist)
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 30, 2003   4:01 PM
+
+Tucker said:
+
+> ...  As a language designer/enhancer, I always want the new features to
+look
+> like they were "always" there, so the language is seamless and there is no
+> obvious dividing line between old and new features.
+
+That's clearly an impossible goal in this case, and using it as a criteria
+is going to lead you nowhere.
+
+The reason for that we're trying to do something unnatural to the basic
+design of Ada: use something before it is declared. In order to do that, we
+have to create some feature that allows using something that isn't even
+declared yet. In order to make that implementable without major disruptions
+(and that is a requirement politically, if not technically), it has to be
+heavily restricted. But heavily restricting something is by itself
+unnatural: usually, if you can declare something in one place, you can
+declare it somewhere else as well (assuming appropriate visibility).
+
+Moreover, any of solution of this sort requires making some subset of
+"class" visible prematurely. And that, is, of itself, unnatural and
+potentially error-prone. (At least Ada will check for problems at
+compile-time, but its better to not have to do that in the first place.)
+
+Any 'natural' solution would have to get rid of special cases and probably
+eliminate most of the compilation order rules. But any such solution would
+not be in the spirit of Ada.
+
+To make the point clear, here is a quick look at every alternative offered
+and why its unnatural (I'll do them in proposal order to avoid bias, and I'm
+going to try to avoid any technical issues):
+ 1) With type. Unnatural because it's the only context clause item on
+non-program units. Unnatural because its restricted to incomplete types
+only. Why not private types or constants?
+ 2) Package abstracts. 3 package parts aren't enough apparently, so let's
+add a fourth. Sheesh. This is a clear violation of the zero, one, or many
+rule of good design. What goes in the extra part certainly isn't clear or
+natural - you'd put whatever you had to in there to make the design work.
+ 3) Old type stubs (explicit completions). The idea of a stub is natural
+enough, but limiting its use to very restricted cases isn't. The completion
+syntax is new, but that hardly makes it unnatural. (Humm, I can't figure out
+why this one would be unnatural. Too bad everyone hates it. I note that it
+eliminates two of Tucker's concerns as well...)
+ 4) Current type stubs. As with the previous case, stubs are natural,
+restricted cases aren't. The concern about having an undeclared dependency
+remains. The limitation to the same name is unnatural, but is easily fixed.
+ 5) Type stubs with a context clause. It's unnatural to use something before
+its declared, whether in the context clause or anywhere else. Otherwise, the
+same as previous.
+ 6) Child package prefixes. These are unnatural because they're limited only
+to the library level of library packages - no higher and no lower. And,
+since they're just warmed over package abstracts, they have all of the
+unnaturalness of that solution as well.
+ 7) Type C.T. This is the most unnatural of all. It has most of the faults
+of both type stubs and package prefixes. First, we're declaring an expanded
+name. This is new for non-program units. OK, but then why is it restricted
+to just incomplete types? Why not deferred constants and by-reference
+objects and private types ...? You're still forced to use these only at the
+library level of library packages (otherwise it couldn't be a child),
+greatly constraining the design. And you still have to figure out when they
+need to be declared separately - and I expect that will occur only when its
+clear that the design won't work any other way. Making people redo their
+design because a need for mutual dependence arises is no better than making
+them redo their existing code.
+
+The real point is that it is not a language designer's job to decide how
+programs ought to be designed, whether they're new, existing, or whatever.
+It's the language's job to give the designers the tools to do that job. No
+one on the ARG can say how Ada programs really are going to be designed
+using these features -- at best, we can only guess. We shouldn't constrain
+those designs unless we really have no choice. (And we shouldn't be saying
+that people can't use "in out" parameters on functions or have a function
+with no return statement, either. But that's a different story.) Type stubs
+have the nice property that they can be used wherever they are needed: in
+library specs, in private parts, in nested packages, even in a protected
+entry body if the need arose. That gives maximum flexibility to the
+designer.
+
+Tucker's philosophy seems to be that 'new designs' should be sets of deeply
+nested child packages. I've tried that design (with Claw), and was not very
+pleased with the results. The primary problem is the package names get very
+long. For me, as a use-adverse programmer that uses full dot notation on
+everything except items declared in the local source text (and its spec,
+with limits) [with very local use/use type clauses for sanity], the clutter
+is awful. That's why CBuild was designed to be mostly flat. Similarly, the
+temptation to use stuff from the parent's private part is strong, and
+impossible to check for. Why allow that? (Of course, if you NEED it, then go
+ahead.) So, for me, (mostly) flat is better. Your mileage may vary. But I
+certainly do not want the language saying: "You have to use deeply nested
+designs. You have to either use "use" clauses or (worse to my view) direct
+visibility from source files that you don't even have open in your editor.
+Or you have to junk all of your current programming tools to use a fancy
+toolset that will let you find declarations in code that you haven't even
+compiled yet (and won't compile, either)."
+
+OK, enough philosophizing. (Gee, is there an echo in here??) :-)
+
+>2) Type stubs are not necessarily "seen" by the type completer.
+
+I suggested a possible fix for this yesterday. I do agree that that would be
+a good idea, but it isn't necessary. The original type stub proposal (with
+explicit completions) clearly does not have this problem (it has other
+problems, of course).
+
+> I think this could have negative implications for compilers
+> like GNAT that have multiple representations for access types
+> (access-to-unconstrained array can be thick or thin, and I
+> presume there is no easy way to convert a thick pointer to a thin one).
+
+This is an existing problem in Ada 95, as you can do this in a package spec.
+deferred to a body. Whatever solution works there should work here. I
+believe GNAT peeks, as you said, and it would have to do that for type
+stubs.
+
+> ...To be specific, we have said that to deal with cases where most types
+have
+> the same simple name (e.g. "Object"), you should use an idiom where a
+separate
+> package is created to hold the type stub.
+
+There is not the slightest problem in fixing this problem; the ARG decided
+NOT to fix this problem. That was a mistake then, and is still a mistake.
+The type stub syntax ought to be something like:
+    type T is separate of P.Object;
+When I originally proposed this, I certainly had no intention on limiting
+the names used, and I still think its an arbitrary restriction that causes
+nothing but trouble. But I was out-voted in Cupertino. C'est la guerre.
+
+> Type stubs have the unfortunate situation where the
+> same type has two different fully expanded names.
+
+What are you talking about? Every entity in Ada can have a multitude of
+names. The names are completely irrelevant. To the extent that type stubs
+talks about names, THAT is a problem. We're only interested in the entities
+matching.
+
+In Janus/Ada at least, there is no difference if the names are the same or
+different. Every declaration makes a unique type slot, so incomplete types
+and private types are different than the completing types. Whether or not
+you're allowed to treat them as the same is handled by a bunch of complex
+rules. And certainly, that would remain true in every proposal made here.
+
+> We have to be focused on the person developing a new abstraction,
+> and how the language can be enhanced in modest ways to
+> enable that person to develop the abstraction without having
+> to stand on their head.
+
+Absolutely. And, in my opinion, forcing use of "unnecessary" child packages
+is precisely that sort of standing on your head. If I redesigned CBuild from
+scratch today, I still would use as few child packages as possible (see
+above). Being forced to use a lot of them just to make Tucker happy makes no
+sense to me at all.
+
+Tucker, I know you believe that everything should be nested in several
+layers of nearly empty packages. Fine, do your software any way you want.
+Can we at least agree that not everyone agrees with your design structure?
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 30, 2003   4:50 PM
+
+Randy Brukardt wrote:
+>
+> Tucker said:
+>
+> > ...  As a language designer/enhancer, I always want the new features to look
+> > like they were "always" there, so the language is seamless and there is no
+> > obvious dividing line between old and new features.
+>
+> That's clearly an impossible goal in this case, and using it as a criteria
+> is going to lead you nowhere.
+>
+> The reason for that we're trying to do something unnatural to the basic
+> design of Ada: use something before it is declared.
+
+But that is exactly what incomplete type declarations are for.
+They are just too restrictive in scope.
+
+In any case, Randy is right that one person's "natural" could be someone
+else's "dog".  To me, extending the incomplete type declaration to
+allow mutual dependence across child or nested packages is natural,
+whereas to him it is an abomination.
+
+
+> ...
+> Tucker, I know you believe that everything should be nested in several
+> layers of nearly empty packages. Fine, do your software any way you want.
+> Can we at least agree that not everyone agrees with your design structure?
+
+I think this is a bit of an exaggeration, but that is of course the
+nature of these debates sometimes.  If we can't sway people with
+our best technical arguments, we try emotional appeals (me too,
+by the way ;-).
+
+We may have to move toward the "Getting to Yes" approach of Camp David
+if we can't come a little closer to consensus on this one.
+
+What *can* we agree on, and thereby at least eliminate some of the
+solutions from the table?  Once we get down to a small enough set
+(hopefully two), we can ultimately just vote (much as I hate losing such votes ;-).
+
+Possible points of consensus:
+
+1) All inter-unit dependence must be either child on parent, body on spec,
+or explicitly mentioned in some applicable context clause.
+
+2) We need a mode of use that works reasonably with the "type Object" paradigm.
+
+3) No new kinds of compilation units (is that still a point of consensus?)
+
+Anything else in our consensus?  Are the above 3 in the consensus?
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 30, 2003   5:03 PM
+
+Arnaud Charlet wrote:
+
+> I don't think an automated tool that would take e.g. existing C or Java
+> headers would be able to easily introduce an extra layer and put every
+> needed circular dependence in the parent package. This would require a
+> global processing of all possible units, and would mean having to
+regenerate
+> everything each time a new unit is added. It would also mean lots of
+> unrelated declarations in the parent package.
+>
+> Unless I am missing something, this is definitely not a very attractive
+> solution if you take the foreign language bindings into account.
+
+This is a red herring. As I mentioned earlier, every solution considered
+requires some sort of unnatural restructuring to use. That's just the nature
+of the problem: we're trying to do something unnatural to the Ada model.
+
+A binding generator simply has to assume that there might be circular
+dependence (and might as well, given that these incomplete declarations
+generate no code). That means generating whatever additional structure is
+necessary to make this circular dependence possible.
+
+For the particular proposal you are responding to, clearly every binding
+would have a wrapper package that contained the incomplete type. A bit ugly
+perhaps, but hardly a major problem. For type stubs, there would be a
+separate "interface" package containing the incomplete type and an access
+type to use everywhere. With type also needs such a separate type package
+unless you never need a named access type (which seems unlikely given the
+heavily pointered nature of those other languages). And for a package
+prefix/abstract, you'd need the prefix. So there doesn't seem to be any
+advantage to any of these proposals this way.
+
+Obviously, you could "optimize" these extra artifacts away, but I think that
+would be a bad idea, because, as you say, adding another class to the
+program could change which ones are needed.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 30, 2003   5:18 PM
+
+Tucker was confused by my sentence:
+
+> > We could get the advantages of (1) and not have the requirement to force
+the
+> > design, by requiring that the completion with the package containing the
+> > stub.
+>
+> This sentence no verb. ;-)
+
+And I couldn't parse it either when I replied. But it does have a verb:
+"with", in the Ada sense. If I could write these messages in HTML, it would
+have been in bold and would have made more sense:
+
+We could get the advantages of (1) and not have the requirement to force the
+design, by requiring that the completion WITH the package(s) containing the
+stub.
+
+I don't know if that makes it any clearer, but I hope so. Then we could
+simplify the completion rules, because the stub would always be available if
+the completion is. (There may be some simplification possible even without
+this rule, but I think it would be more natural with it.) I'd pursue this
+further, but I have a lot of other work I need to do before the meeting.
+
+*************************************************************
+
+From: Dan Eilers
+Sent: Thursday, January 30, 2003   6:04 PM
+
+Tucker wrote:
+> Anything else in our consensus?  Are the above 3 in the consensus?
+
+
+I don't know if it rises to the level of consensus, but it seems highly
+desirable from a usability point of view to require that clients of a
+circular type not have to change on account of the circularity.
+
+That means if there was previously a package Employees, with a type
+Employee, and Employee was made circular with Departments.Department,
+then clients could still "with" package Employees, and still refer to
+type Employees.Employee.
+
+Specifically, we can't require the client to use an invented
+parent unit such as Directory.Employees.Employee, nor can we require
+use of an invented child unit, such as Employees.Extension.Employee.
+Nor do we want to require library-level renames to satisfy this
+requirement.
+
+Both the "with type" proposal and the "package abstracts" proposals
+seem to meet this requirement, as does my proposal to put the "abstract"
+in a child unit that can be compiled before its parent.  The early
+type-stub proposal allowing the stubs in an unrelated package also
+works.  But the modified type-stub proposal restricting the full type
+to a child, as well as the package-prefix proposals both fail.
+
+The difficulty seems to stem from the fact that child units are the
+natural Ada way to extend a package, but the client should "with" the
+main package, not an invented child containing the type completions.
+
+A solution we haven't considered would be to allow a package spec to
+be extendible via package subunits, which would contain the completions
+of incomplete types in the package spec.  The subunits wouldn't be
+"withable" by clients, but would be automatically included in any
+"with" of the main package.  A different kind of "with" clause would
+be used to "with" the main package without its subunits (i.e., the
+abstract of the main package).  Something like "with employees'abstract".
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 30, 2003   6:13 PM
+
+(BTW, sorry about answering some old messages a second time. I was filing
+the mail, and some of the statements bothered me enough that I felt
+compelled to reply -- not remembering that I did so yesterday. I think 44 is
+too young to get Alzheimer's. :-)
+
+Anyway,
+
+Tucker wrote:
+> But that is exactly what incomplete type declarations are for.
+> They are just too restrictive in scope.
+>
+> In any case, Randy is right that one person's "natural" could be someone
+> else's "dog".  To me, extending the incomplete type declaration to
+> allow mutual dependence across child or nested packages is natural,
+> whereas to him it is an abomination.
+
+I'd agree with the premise, but the point is that that is exactly what type
+stubs are supposed to be. Certainly, the original proposal with explicit
+completion was designed that way precisely so that it was a natural
+extension of the existing syntax and semantics. And that's still true with
+the current one: it is just a different name (like a subtype) for the
+completing type. You'll get all confused if you start paying attention to
+exactly how that is accomplished. (That happens a lot in Ada; often, you're
+better off not trying to understand the detailed rules unless you're an
+implementor or language lawyer.) So I don't see any difference in the user
+model for either of these proposals, only that type stubs isn't restricted
+in how or where it can be used, and the Tucker "type C.T;" is restricted.
+
+OTOH, it's a bit unnatural that this doesn't work for private types. More
+generally, the problem is that Ada has several kinds of "restricted
+visibility types", and really, that should have been a more general
+mechanism, rather than a series of special kinds of types. Of course, its
+too late to fix this in any useful way.
+
+> > ...
+> > Tucker, I know you believe that everything should be nested in several
+> > layers of nearly empty packages. Fine, do your software any way you want.
+> > Can we at least agree that not everyone agrees with your design structure?
+>
+> I think this is a bit of an exaggeration, but that is of course the
+> nature of these debates sometimes.  If we can't sway people with
+> our best technical arguments, we try emotional appeals (me too,
+> by the way ;-).
+
+The very first response you made to my original type stub proposal was
+"...and I wouldn't mind requiring it to be a child of the package where the
+incomplete type is declared,..." (July 9, 2001), so it seems to me that you
+are always thinking in that direction. (How else could you stomach
+restricting uses this way?) In any case, I was just trying to make sure that
+you hadn't lost sight of all of the different ways Ada is used.
+
+> ...
+> What *can* we agree on, and thereby at least eliminate some of the
+> solutions from the table?  Once we get down to a small enough set
+> (hopefully two), we can ultimately just vote (much as I hate
+> losing such votes ;-).
+
+I fear that there is not much.
+
+> Possible points of consensus:
+>
+> 1) All inter-unit dependence must be either child on parent, body on spec,
+> or explicitly mentioned in some applicable context clause.
+
+I can agree with this as written, because a type stub doesn't introduce
+dependence. :-) So, from a language lawyer/implementor perspective, we're
+fine.
+
+But, clearly, there are some people who think that this
+not-really-dependence needs to be in the context clause. Obviously, we need
+to address their concern, but there is another alternative to agreeing with
+this point: re-education. After all, Ada 83 didn't have the invisible child
+on parent dependence, and it isn't clear from the context clause. Indeed, I
+often forget that it exists, which is one reason that my personal coding
+rules do not allow using the direct visibility on the parent to simplify
+names. So, I don't see any horrible problem with adding another hidden
+dependence, particularly when its not really a dependence at all (any change
+to the completing package has no effect on the stub's package, so there is
+no issue).
+
+I really don't care either way, so if there is some strong support for this
+position, I would be happy to go that way. (Which is why I prepared
+alternative #5, so we could compare the wording changes needed with or
+wothout such a context clause.)
+
+> 2) We need a mode of use that works reasonably with the "type Object"
+> paradigm.
+
+I've always agreed with this. But I wonder if the whole ARG does, because we
+voted down making type stubs do this. And I see no reason to require the
+names to match: we don't do that for other sorts of renaming, why here?
+
+> 3) No new kinds of compilation units (is that still a point
+> of consensus?)
+
+I'd rather not have any, but I must admit that it is the only way that I can
+see to reconcile my viewpoints with yours. But I don't know if we can afford
+to have new kinds of units.
+
+> Anything else in our consensus?  Are the above 3 in the consensus?
+
+Well, I think we should include:
+
+0) We have to have a solution to mutually dependent types in the Amendment.
+This is a very important problem which simply has to be solved (even if the
+solution is ugly).
+
+4) We have to be able to automatically translate headers from C++ or Java
+into Ada using this feature.
+
+I'd probably add, but don't know if it is a consensus point:
+
+5) The model has to be reasonably easy to explain to the average experienced
+Ada programmer.
+(Because if we had done that the first time, we wouldn't be talking about it
+now.)
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 30, 2003   9:53 PM
+
+Dan Eilers wrote:
+
+> I don't know if it rises to the level of consensus, but it seems highly
+> desirable from a usability point of view to require that clients of a
+> circular type not have to change on account of the circularity.
+
+For what its worth, thanks to library unit renaming, I don't see
+any need for clients to change with the "type C.T;" approach.
+For those situations where child packages just
+won't do, you could use an approach like the following:
+
+package Top is
+    type Departments.Department;
+    type Employees.Employee;
+    ... -- any others needed to break circularity among
+    ... -- top level packages
+end Top;
+
+package Top.Departments is
+    type Department is ...
+
+    procedure Add_Employee(Dpt : in out Department;
+      Emp : access Employees.Employee);
+    ...
+end Top.Departments;
+
+with Top.Departments;
+package Departments renames Top.Departments;
+
+
+
+package Top.Employees is
+     type Employee is ...
+
+     procedure Set_Manager(Emp : in out Employee;
+       Mgr : access Managers.Manager);
+     ...
+end Top.Employees;
+
+with Top.Employees;
+package Employees renames Top.Employees;
+
+
+Essentially, this is using "Top" as a package
+where you can place the incomplete type declarations
+for what are intended to be top-level library units,
+if they are needed to break circularity.
+[In this case we have placed both Departments.Department
+and Employees.Employee into Top, but you could normally
+get away with just one of them, since breaking
+the circularity only requires one incomplete type declaration.]
+
+It is then expected that all children of "Top"
+will be renamed to be top-level library units
+for use by clients.
+
+If you generally design using package hierarchies,
+then rarely will you have to use the "Top" trick.
+E.g., both Departments and Employees might have
+already been children of package Office, or Departments
+might have been a child of Employees.
+
+But in a pinch where you need mutual dependence
+between packages that are not inside the same
+package hierarchy, using a single "Top" parent
+for all such packages would work.  It is almost
+as though you were able to add incomplete type
+declarations into the spec for Standard.
+
+In fact, we could consider treating an explicit
+declaration of a package Standard as meaning
+"these are declarations to add at the end of my
+package standard," but that would be incompatible
+with all those folks out there who really do
+have a library package called Standard (Standard.Standard,
+that is).
+
+I suppose compiling a file containing
+only pragmas is similar to placing the pragmas in
+package Standard, so this would be somewhat similar
+to library-wide configuration pragmas.
+
+Of course, you could also have a separate "Top"-like
+package for each logical group of packages that
+have a mutual dependence, but that begins to smell
+like a package hierarchy again ;-).
+
+*************************************************************
+
+From: Robert A. Duff
+Sent: Friday, January 31, 2003  12:01 PM
+
+Randy said:
+
+> Well, I think we should include:
+>
+> 0) We have to have a solution to mutually dependent types in the Amendment.
+> This is a very important problem which simply has to be solved...
+
+Well said.
+
+I would be perfectly happy with the original ARG-approved proposal that
+WG9 rejected.  There were two concerns:
+
+    - It seems bad to mention package names that aren't 'with'-ed.
+      A perfectly legitimate response is: Yes, this is a legitimate
+      point, but ARG is unable to fix the problem in the available time,
+      and anyway, it's hardly a big deal.
+      The other alternative is to add a new kind of with clause that
+      does *not* introduce a dependency (in fact, it doesn't do much of
+      anything except suppress a certain error message).  That's
+      reasonable too, but I don't think we *have* to do that.
+
+    - The "every type called Object" issue.  Well, it seems to me that
+      when you choose this style, you are limiting yourself to one type
+      per package (or at least one type called "Object" per package --
+      presumably the "main" type).  So you need to create packages to
+      hold all the type stubs.  So what?
+
+Tucker doesn't like that proposal, for aesthetic reasons he has been
+unable to articulate to *my* satisfaction.  Fine.  I'm also perfectly
+willing to go along with Tucker's recent "type C.T;" proposal.  Tucker
+has demonstrated that it is possible to add cycles without editing
+clients, even in systems that do not currently use child units.  That
+should address Dan's concern.  I also don't buy Randy's objections --
+you don't need to introduce a whole bunch of child levels, you need to
+introduce either zero or one.  And in the latter case, you can rename it
+away as Tucker demonstrated.
+
+Tucker's latest proposal does seem a bit simpler, and a bit easier to
+implement.  And using incomplete types is a perfectly natural way to
+address this issue.
+
+Pascal, as our esteemed chair, please lock these folks in a room in
+Padua, and don't let them out until they agree upon a solution.  ;-)
+
+*************************************************************
+
+From: Dan Eilers
+Sent: Friday, January 31, 2003  12:51 PM
+
+Tucker wrote:
+> For what its worth, thanks to library unit renaming, I don't see
+> any need for clients to change with the "type C.T;" approach.
+
+yes, that is workable, but looks to me like a "dog".  Ideally,
+one class in other languages should be implementable with one
+Ada package.  Two is a stretch, and the third (library renaming)
+exceeds my threshhold of "dog".
+
+I'd like to know if we really have a requirement to solve the
+circular types problem for non-private types?
+
+If we can limit ourselves to private types, and if we also intend
+to solve the "private is separate" problem (which I hope we do),
+then I think one simpler solution solves both problems (just like
+circular types can be defined within a single package using private
+types instead of incomplete types).
+
+You would have some syntax, such as "private is separate" to say
+the private part is separately compiled.  A normal "with" clause would
+continue to cause a semantic dependence on both the public part and
+the separately compiled private part.  A different kind of "with" clause,
+such as "with p'abstract", would semantically depend on only the public
+part.  This is what would be used at the top of the separately compiled
+private parts to avoid'circular semantic dependencies.
+
+This reduces the proposed 3-compilation-unit solution down to
+just one compilation unit with a separately compiled private part.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Friday, January 31, 2003  8:28 PM
+
+The problem is that the visible parts depend on one another,
+not just the private parts.  They each have visible operations
+that mention the other in formal parameters, presumably
+via an access type.  This problem isn't solved by deferring
+the private part, as far as I can see.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Friday, January 31, 2003  9:04 PM
+
+Robert A Duff wrote:
+ > ...
+> Tucker doesn't like that proposal, for aesthetic reasons he has been
+> unable to articulate to *my* satisfaction.
+
+Yes I have aesthetic concerns, but I realize those are
+not easily conveyed to others.  Basically, we have a totally
+new construct that looks like nothing that appears anywhere
+else in the language, and somewhat tortures the meaning
+of "separate."
+
+But my *non* "aesthetic" concerns (over and above
+the two concerns expressed by SIGAda 2002 attendees) are
+hopefully easier for others to understand, if
+not agree with:
+
+- it ends up creating two (or more) fully expanded names
+   for the same type, with new, tricky-to-define-and-implement
+   rules for when the names are equivalent;
+- the recommended idiom of use seems to indicate that
+   type stubs really belong in a "prefix" or "abstract"
+   (or parent) part of the unit, not in some randomly named unit;
+- the completing unit doesn't see the type stub, nor
+   even know it exists, so it doesn't "know" it needs
+   to match an access type representation that will be
+   used by units that see only a stub.
+
+[To address this third concern, Randy has
+suggested requiring that the completing package
+must "with" (all) the package(s) containing the stub(s).  This
+seems difficult to enforce, since you seem to have recreated
+the cyclic recompilation problem we were trying to eliminate.
+I.e., when you add a new stub somewhere, you have to go and
+check that the package referenced by the stub has a "with"
+clause on it, but there is no requirement that the package
+even exist, and in any case, it might be changed later.
+So when you (re)compile the completing package, you must scan all units
+in the system and see whether they now contain a stub.
+This seems to be creating a mutual compilation dependence between
+a unit containing a stub and the completing package,
+which sounds painful.]
+
+ > ...
+> I'm also perfectly
+> willing to go along with Tucker's recent "type C.T;" proposal....
+ >
+> Tucker's latest proposal does seem a bit simpler, and a bit easier to
+> implement.  And using incomplete types is a perfectly natural way to
+> address this issue.
+
+Glad to hear that even if my aesthetic concerns about
+type stubs are unconvincing, that the "type C.T" alternative
+isn't dead on arrival as far as you are concerned...
+
+> Pascal, as our esteemed chair, please lock these folks in a room in
+> Padua, and don't let them out until they agree upon a solution.  ;-)
+
+Sounds like fun.  I'll bring the Chianti... ;-) ;-)
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Friday, January 31, 2003  10:17 PM
+
+> - it ends up creating two (or more) fully expanded names
+>    for the same type, with new, tricky-to-define-and-implement
+>    rules for when the names are equivalent;
+
+The number of names is meaningless; it's how many types there are that
+matters. The point about the complexity of matching the types is true, but I
+think it's a self-inflicted problem.
+
+...
+> [To address this third concern, Randy has
+> suggested requiring that the completing package
+> must "with" (all) the package(s) containing the stub(s).  This
+> seems difficult to enforce, since you seem to have recreated
+> the cyclic recompilation problem we were trying to eliminate.
+
+It's clearly a post-compilation check. That is, it's not enforced until the
+partition is created. It doesn't have to be anything else, I think. (After
+all, the existence of a child with the right name is essentially a post
+compilation check, at least from the perspective of the stub.)
+
+> I.e., when you add a new stub somewhere, you have to go and
+> check that the package referenced by the stub has a "with"
+> clause on it, but there is no requirement that the package
+> even exist, and in any case, it might be changed later.
+> So when you (re)compile the completing package, you must scan all units
+> in the system and see whether they now contain a stub.
+> This seems to be creating a mutual compilation dependence between
+> a unit containing a stub and the completing package,
+> which sounds painful.]
+
+That's definitely not the model I had. My concern is simply that there be no
+views of the completion that can't see (all) of the stubs for that
+completion. (That's the main gain of your proposal, I think.)
+
+...
+> > Pascal, as our esteemed chair, please lock these folks in a room in
+> > Padua, and don't let them out until they agree upon a solution.  ;-)
+>
+> Sounds like fun.  I'll bring the Chianti... ;-) ;-)
+
+Better bring a lot... :-) :-) :-)
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Friday, January 31, 2003  9:06 AM
+
+One way to make progress might be to compare
+attempts at actual wording for these various
+proposals.  (I figure we don't have a shortage
+of material for the AI "discussion" sections ;-).
+
+Here is an attempt to provide wording
+for the "incomplete child type" proposal.
+
+[I have ignored the "is tagged" part
+in the wording, because it is probably
+time for us to separate tagged incomplete types out
+into their own AI, as at this point they seem orthogonal
+to our debate over the solution to the mutually dependent
+packages problem.]
+
+--------- proposed wording -------
+
+Change paragraphs 3.10.1(2,3) as follows ("{}" are additions,
+"[]" are deletions, except in the syntax part):
+
+incomplete_type_declaration ::=
+   TYPE {[package_identifier.]}defining_identifier[discriminant_part]
+     {[is tagged]};
+
+An incomplete_type_declaration requires a completion, which shall be
+a full_type_declaration {, a private_type_declaration, or a
+private_extension_declaration}.  {If a package_identifier
+is present in the declaration, the completion shall occur immediately
+within the visible part of a package with this identifier,
+which shall be declared later and immediately within the innermost
+enclosing declarative region.  Otherwise, if}[If] the
+incomplete_type_declaration  occurs immediately within ...
+    < rest remains the same >.
+
+Add the following sentences to the end of paragraph 3.10.1(11):
+
+If a package_identifier is present in the declaration, the
+incomplete type is declared immediately within the declarative
+region of the named package.  Otherwise, the incomplete type is
+declared immediately within the innermost enclosing declarative region.
+
+Change 8.3(19) as follows:
+
+If the completion of a declaration is a declaration, then [within
+the scope of] {in places where} the completion {is visible}, the
+first declaration [is] {, and any declarations it completes, are}
+hidden from all visibility.  Similarly, a discriminant_specification
+or parameter_specification is hidden [within the scope of]
+{in places where} a corresponding discriminant_specification
+or parameter_specification of a corresponding completion, or
+of a corresponding accept_statement {is visible}.
+
+--------- end of wording ----------
+
+This last part deserves some discussion.  The change from "within the
+scope" to "places where visible" seems necessary for any of our
+proposals, to avoid the "ripple" effect where an indirect "with"
+dependence can have significant effects on a unit outside the
+scope of the "with" clause.
+
+The original "within scope" wording would pull completions
+into all semantic dependents of the completing package, since the
+scope of a library item extends to all its dependents, including
+those units that do not have "with" visibility on the _item.  But
+we have agreed in past discussions that we want the completing
+package (or a rename thereof) to be visible, not just somewhere
+within scope, if we are going to consider the type "completed."
+The new wording of the paragraph is intended to have no effect
+on existing code.
+
+One note about the syntax, to address Randy's concern.  Adding the
+optional "[package_identifer.]" to the syntax could be treated by the
+parser roughly in the same way as the optional "[parent_unit_name.]"
+is treated in section 6.1 for defining_unit_name.  You could allow
+this prefix on any type declaration, and then have a semantic
+rule that makes sure it is only used for incomplete type
+declarations.
+
+My belief is that this proposal will have the simplest wording
+and implementation effort, and with the use of the "Top" package
+approach I mentioned in an earlier message, can accommodate use of
+the feature for packages that are not part of a package
+hierarchy.
+
+*************************************************************
+

Questions? Ask the ACAA Technical Agent