CVS difference for ais/ai-60217.txt

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

--- ais/ai-60217.txt	2003/08/01 01:40:10	1.6
+++ ais/ai-60217.txt	2003/08/08 01:44:12	1.7
@@ -370,14 +370,14 @@
 From: Tucker Taft
 Sent: Thursday, February 13, 2003  2:48 PM
 
-I was tasked with writing up the "type C.T;" proposal.  Here it
-is. [Editor's note: This is version /01 of the AI.]
-One interesting option presented itself as I was working on it.
-If we permit these incomplete types to be completed by a renaming
-of a package, then the packages participating in the cycle can
-all be declared as top-level library units.  See example (d) in
-the AI for how this might look.  I think this paradigm might
-alleviate the concern about being forced to use child units.
+I was tasked with writing up the "type C.T;" proposal.  Here it is. [Editor's
+note: This version of the AI was not posted; version /01 is similar and more
+complete.] One interesting option presented itself as I was working on it. If
+we permit these incomplete types to be completed by a renaming of a package,
+then the packages participating in the cycle can all be declared as top-level
+library units.  See example (d) in the AI for how this might look.  I think
+this paradigm might alleviate the concern about being forced to use child
+units.
 
 **************************************************************
 
@@ -388,7 +388,7 @@
 it wasn't complete.  In particular, it lacked rules
 on when A.all := B.all would be legal, and it didn't
 have any post-compilation rules regarding when a child
-package was "needed," etc. [Editor's note: This is version /02 of the AI.]
+package was "needed," etc. [Editor's note: This is version /01 of the AI.]
 
 Also, it is really variant "7" rather than "VIII" (sorry about
 that, can't imagine how I lost count ;-
@@ -436,6 +436,1371 @@
 We are only dealing with cases where both the incomplete type and the
 completion are in scope, but by different fully expanded names,
 which has got to be rare.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Saturday, March 22, 2003  12:15 AM
+
+
+This example shows two ways that I would use alternative #7 of AI-217
+in the Claw Builder. See the similar write-up on alternative #5 for details
+about the Builder and why it is important to be able to use this facility in
+it.
+
+[Editor's note: Here are those details.]
+
+The Claw Builder is a real, existing program which could use this facility.
+The problem is that some objects need references to other types of objects,
+and these needs are circular. For instance, (some) types of window objects
+include menu objects. And some types of menu objects include actions that
+open a window.
+
+The current Claw Builder solves this problem by using names rather than
+access objects to connect the objects in some cases. This is usually done
+only where necessary to break circularities. For instance, menu objects name
+the windows they are to open, rather than linking to them. Using names
+causes several problems:
+   -- Accesses to the linked object is much slower, as they have to be
+      looked up by name before use;
+   -- If the user renames the linked object, we have to walk the entire
+      project to insure any names are updated;
+   -- If the user copies the linked object and then renames the copy (the
+      required behavior), we have to be careful NOT to walk the project
+      and update names -- harming code reuse.
+   -- We can't have overloaded names (not a problem for windows, but can
+      happen in other cases).
+
+A root window object is an abstract object with a fairly large set of
+operations. Each concrete object has to provide implementations for many of
+these operations (some it can inherit). All of these operations are
+dispatching. Typically, a user of the operation would apply it to a list of
+windows using an iterator generic, with the operation dispatching to the
+correct implementation. For the purposes of this discussion, we'll look at
+just a few: Show, Hide, Display_Name.
+
+The existing package looks something like:
+
+   with CBuild_Menu;
+   package CBuild_Root is
+      type Root_Window_Type is abstract new
+	    Ada.Finalization.Limited_Controlled with private;
+      type Any_Window_Access_Type is access all Root_Window_Type'Class;
+
+      procedure Show (Window : in out Root_Window_Type) is abstract;
+      procedure Hide (Window : in out Root_Window_Type) is abstract;
+      function Display_Name (Window : in Root_Window_Type)
+          return String is abstract;
+      ...
+   private
+      type Root_Window_Type is abstract new
+	    Ada.Finalization.Limited_Controlled with record
+          ... CBuild_Menu.Something ...
+      end record;
+   end CBuild_Root;
+
+The menu package looks something like (greatly simplified):
+
+  with CBuild_Id_Type;
+  package CBuild_Menu is
+    type Menu_Item is record
+       Name : String (1..20);
+       Action : Action_Type;
+       Dialog : CBuild_Id_Type; -- The name of a dialog window.
+           -- If Action=Open_Dialog.
+    end record;
+    procedure Simulate_Action (Item : in Menu_Item);
+  end CBuild_Menu;
+
+  with CBuild_Root, CBuild_Lists;
+  package body CBuild_Menu is
+    procedure Simulate_Action (Item : in Menu_Item) is
+    begin
+       if Item.Action = No_Action then
+           null;
+       elsif Item.Action = Open_Dialog then
+           CBuild_Root.Show (
+                 CBuild_Lists.Lookup(Item.Dialog,
+                     CBuild_Data.Top_Level_Window_List));
+       ... -- Other actions.
+       end if;
+    end Simulate_Action;
+  end CBuild_Menu;
+
+[End details copied from alternative #5.]
+
+Alternative #7 requires the use of a child package to hold the main
+definition. Thus, we have to add a parent whose primary purpose is to be the
+abstract. (Again we're assuming that AI-326 is approved.)
+
+   package CBuild_Definitions is
+      type Root.Root_Window_Type is tagged;
+      type Any_Window_Access_Type is access all Root_Window_Type'Class;
+   end CBuild_Definitions;
+
+This parent package would be used directly when you need to declare
+instances (usually components) of the type in locations where the reference
+would be circular.
+
+In order to keep the use of the access types compatible with the existing
+definition, we'll need to subtype the access type in the main package. And
+of course, it has to be the child package named.
+
+   with CBuild_Menu;
+   package CBuild_Definitions.Root is
+      type Root_Window_Type is abstract new
+	    Ada.Finalization.Limited_Controlled with private;
+      subtype Any_Window_Access_Type is
+CBuild_Definitions.Any_Window_Access_Type;
+
+      procedure Show (Window : in out Root_Window_Type) is abstract;
+      procedure Hide (Window : in out Root_Window_Type) is abstract;
+      function Display_Name (Window : in Root_Window_Type)
+          return String is abstract;
+      ...
+   private
+      type Root_Window_Type is abstract new
+	    Ada.Finalization.Limited_Controlled with record
+          ... CBuild_Menu.Something ...
+      end record;
+   end CBuild_Definitions.Root;
+
+In order to avoid having to change every existing use of the package, we'd
+need to define a library level rename:
+
+    with CBuild_Definitions.Root;
+    package CBuild_Root renames CBuild_Definitions.Root;
+
+The client package (in this case, for menus) would look something like:
+
+  with CBuild_Definitions;
+  package CBuild_Menu is
+    type Menu_Item is record
+       Name : String (1..20);
+       Action : Action_Type;
+       Dialog : CBuild_Definitions.Any_Window_Access_Type;
+           -- If Action=Open_Dialog.
+    end record;
+    procedure Simulate_Action (Item : in Menu_Item);
+  end CBuild_Menu;
+
+  with CBuild_Root;
+  package body CBuild_Menu is
+    procedure Simulate_Action (Item : in Menu_Item) is
+    begin
+       if Item.Action = No_Action then
+           null;
+       elsif Item.Action = Open_Dialog then
+           CBuild_Root.Show (Item.Dialog.all);
+       ... -- Other actions.
+       end if;
+    end Simulate_Action;
+  end CBuild_Menu;
+
+The reasons I didn't like the first solution in my last note hold here, too:
+it's not clear when to use the definitions package, and when to use the main
+package. It would be preferable to keep an understandable separation between
+them.
+
+As before, we could create a "client" package and a "creator" package. The
+"client" package  would be used by ordinary client packages of the
+abstraction. The "creator" package would be used only by packages that need
+to create new extensions of the type or create objects of the type. The
+"creator" package would, of course, be similar to the existing package. The
+"client" package would provide enough operations that regular clients could
+use it only.
+
+Since the "client" package would be used most frequently, I've given it the
+existing name, and thus it would be the parent package:
+
+   package CBuild_Root is
+      type Creator.Root_Window_Type is tagged;
+      type Any_Window_Access_Type is access all Root_Window_Type'Class;
+
+      procedure Show (Window : in out Root_Window_Type'Class);
+      procedure Hide (Window : in out Root_Window_Type'Class);
+      function Display_Name (Window : in Root_Window_Type'Class)
+          return String;
+      ...
+   end CBuild_Root;
+
+The "creator" package would be as in the previous example (except for the
+name):
+
+   with CBuild_Menu;
+   package CBuild_Root.Creator is
+      type Root_Window_Type is abstract new
+	    Ada.Finalization.Limited_Controlled with private;
+      subtype Any_Window_Access_Type is CBuild_Root.Any_Window_Access_Type;
+
+      procedure Show (Window : in out Root_Window_Type) is abstract;
+      procedure Hide (Window : in out Root_Window_Type) is abstract;
+      function Display_Name (Window : in Root_Window_Type)
+          return String is abstract;
+      ...
+   private
+      type Root_Window_Type is abstract new
+	    Ada.Finalization.Limited_Controlled with record
+          ... CBuild_Menu.Something ...
+      end record;
+   end CBuild_Root.Creator;
+
+The body of CBuild_Root would need visibility on the completing type so that
+it
+could implement the procedures, meaning it would have to with the Creator
+package:
+
+   with CBuild_Root.Creator;
+   package body CBuild_Root is
+      procedure Show (Window : in out Root_Window_Type'Class) is
+      begin
+          CBuild_Root_Definition.Show (Window);
+      end Show;
+      procedure Hide (Window : in out Root_Window_Type'Class) is
+      begin
+          CBuild_Root_Definition.Hide (Window);
+      end Hide;
+      function Display_Name (Window : in Root_Window_Type'Class)
+          return String is
+      begin
+          return CBuild_Root_Definition.Display_Name (Window);
+      end Display_Name;
+      ...
+   end CBuild_Root;
+
+As before, with this structure, the clients with CBuild_Root, and the
+concrete object packages with (or are children of) CBuild_Root_Definition.
+The two packages have clearly defined roles.
+
+For instance, the menu case would look something like:
+
+  with CBuild_Root;
+  package CBuild_Menu is
+    type Menu_Item is record
+       Name : String (1..20);
+       Action : Action_Type;
+       Dialog : CBuild_Root.Any_Window_Access_Type;
+            -- If Action=Open_Dialog.
+    end record;
+    procedure Simulate_Action (Item : in Menu_Item);
+  end CBuild_Menu;
+
+  package body CBuild_Menu is
+    procedure Simulate_Action (Item : in Menu_Item) is
+    begin
+       if Item.Action = No_Action then
+           null;
+       elsif Item.Action = Open_Dialog then
+           CBuild_Root.Show (Item.Dialog.all);
+       ... -- Other actions.
+       end if;
+    end Simulate_Action;
+  end CBuild_Menu;
+
+which is unchanged from the alternative #5 version.
+
+---
+
+Of course, the best way to avoid the issue of deciding when to use one of
+the two packages is to avoid having the second one in the first place.
+Unfortunately, this alternative (unlike the other two) does not allow that.
+The restrictions on the placement of the stub mean that there is no way to
+avoid having to 'with' two different packages in the specification and body
+of CBuild_Menu.
+
+The closest we can come would be to wrap the entire program in a parent
+package. Then we could put the stub into that wrapper, and no with would be
+needed to access it. Of course, the with is still there, the only difference
+is that it is implicit. Moreover, this would require changing the
+declaration of every compilation unit in the program (there's now over 100
+units in the Claw Builder) - and, if we continue to follow our coding
+standard, most of the uses as well.
+
+There is an even more serious problem with this proposal, which is that it
+isn't responsive to the SIGAda concerns. The dependence implied in the stub
+definition is not natural (parents do not usually know about their children)
+and is well hidden deep in the package specification, not clearly specified
+in the context clause.
+
+That isn't obvious in these examples, but would be if the many lines of
+header comments and change log entries were included before the start of
+declarations in the package. A typical package has a 25-line copyright
+message, the context clause and package header, then a description of the
+program, a description of the function of the package, and an edit history,
+before any declarations.
+
+I'll have more to say about this sometime when I'm awake.
+
+
+That concludes my look at using alternative #7 in CBuild. Coming soon: a
+similar look at alternative #6.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 26, 2003  1:53 PM
+
+Randy said:
+
+> type C.T does not meet the SigAda criteria IMO, and I'm thinking about it as
+> little as possible. I'd motion to kill it, but I'll have to wait until June
+> to do that.
+
+I guess I object to this attitude.  I think the "SIGAda"
+participants did not consider this proposal, so it is
+hard to say whether they would consider a stub in
+a parent adequate "notice" of the existence of a
+dependence.  In my view, it corresponds quite similarly
+to the "notice" provided for subunits.
+
+In any case, I will try to present the three alternatives
+to AdaUK in a couple of weeks, and see if we can get
+some more helpful user feedback.  I would encourage
+Pascal to produce something soon, even if it lacks
+detailed wording, so long as it captures his intent
+in a way that others can review it.
+
+Many of us still believe this is one of the most
+important Ada 200Y issues.
+
+**************************************************************
+
+From: Dan Eilers
+Sent: Wednesday, March 26, 2003  2:09 PM
+
+>              In my view, it corresponds quite similarly
+> to the "notice" provided for subunits.
+
+So why not just use subunits as the mechanism?
+The notice provided by subunit stubs is presumably adequate.
+And you can use the "limited with" syntax to indicate
+"with"ing a unit without creating a semantic dependence
+on the subunits declared in its spec.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Thursday, March 27, 2003  5:42 AM
+
+> So why not just use subunits as the mechanism?
+> The notice provided by subunit stubs is presumably adequate.
+> And you can use the "limited with" syntax to indicate
+> "with"ing a unit without creating a semantic dependence
+> on the subunits declared in its spec.
+
+First, existing subunits are defined semantically by
+being substituted at the point of the stub.  That is
+exactly *not* what we want to do.
+
+Secondly, I tend to agree with Randy that any proposal
+that requires both a new kind of context clause and a
+new kind of incomplete type stub seems more complex
+for the user than a proposal that requires only one or
+the other.  "Limited with" seems to have a lock on
+the best solution that requires only a context clause.
+
+For the stub-only alternative, we need to find an incomplete
+type stub that is considered by users to be sufficiently
+visible and well-defined on its own to not require a
+special context clause as well.  My view is that the
+incomplete child type proposal does that.  But that is
+just my view, and it is clear that at least Randy either
+doesn't like its syntax and/or its reliance on the child
+relation, or believes that there is no incomplete type
+stub of any syntax or semantics that would pass muster
+with users unless it has a special context clause as well.
+
+One possibility it to try to make the incomplete child
+type stub more "visible" by adding more reserved words,
+such as "separate."  Another is to move the incomplete
+child type stub into the context clause, or require it
+precede all other declarations inside the parent.
+But none of these address the other objection to being restricted
+to the child relation.  I find that restriction natural, others
+don't.  And sometimes it is hard to separate negative
+reactions to syntax from negative reactions to semantics.
+
+**************************************************************
+
+From: Dan Eilers
+Sent: Friday, March 28, 2003 11:38 AM
+
+> First, existing subunits are defined semantically by
+> being substituted at the point of the stub.  That is
+> exactly *not* what we want to do.
+
+But it is exactly what we normally want to do.  Normal clients
+want to see the full abstraction, including the completions
+of the incomplete types.  And they want to see the full abstraction
+without having to "with" (or rename) a child unit.
+Only clients involved in the circular dependency need a restricted
+view of the abstraction (to break the circularity), and for that I
+proposed using the "limited with" (or similar) syntax.
+
+I agree that using child units avoids having to add new syntax
+for "with" clauses (since the client can "with" the parent to see
+the restricted view, or the child to see the full view).  But this
+doesn't seem advantageous to the user, since almost all clients
+want to see the full view, and are stuck having to "with" (or rename)
+the child.
+
+The other differences between a subunit solution and a child-unit
+solution all seem to favor subunits:
+  1) the stub of a subunit naturally provides the ideal level of
+     notice of a forthcoming semantic dependency;
+  2) parent units depending on subunits is natural, but
+     parent units depending on child units is unnatural;
+  3) subunits allow an abstraction (package spec) to be divided
+     into separately-compiled pieces while preventing a client
+     from directly "with"ing the pieces containing implementation
+     details that are intended to remain hidden.
+  4) allowing subunit stubs in package specs amounts to removing
+     an unnecessary restriction from the language, but allowing
+     dependencies from a package spec to a child unit amounts to
+     adding a new feature.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Friday, March 28, 2003  7:34 PM
+
+I have to agree with Dan here. It seems that a subunit-based solution might
+be a better approach than alternative 7 ("type C.T;"), because subunits seem
+more natural than child units for this purpose.
+
+However, any solution that requires writing two things is going to be
+inferior to a solution that requires writing one. So, I suspect that
+alternative 6 ("limited with") is likely to carry the day based on better
+usability, even if it gives some implementers heartburn. Of course, if a
+semantic or implementation showstopper is uncovered, we'll end up having to
+revert to one of the other proposals, and in that case, it would be valuable
+to work out a solution based on subunits.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 26, 2003  2:45 PM
+
+> I guess I object to this attitude.  I think the "SIGAda"
+> participants did not consider this proposal, so it is
+> hard to say whether they would consider a stub in
+> a parent adequate "notice" of the existence of a
+> dependence.  In my view, it corresponds quite similarly
+> to the "notice" provided for subunits.
+
+But the same argument applies to the type stubs that you presented at
+SIGAda, and we know for certain that those were not acceptable to those
+participants.
+
+There is no natural dependence from a parent to a child, as opposed to from
+a spec to body or a child to a parent.
+
+> In any case, I will try to present the three alternatives
+> to AdaUK in a couple of weeks, and see if we can get
+> some more helpful user feedback.
+
+I would feel a lot better if an unbiased observer did the presenting at
+AdaUK. The Padua minutes say that John Barnes was going to do that. I know
+that the biases of the presenter can make a substantial impact on the
+results of a discussion (that certainly happened in Padua on this very
+discussion), and I fear that that will color the feedback that we get.
+
+> I would encourage Pascal to produce something soon, even if it lacks
+> detailed wording, so long as it captures his intent
+> in a way that others can review it.
+
+Which points out my other concern. There is absolutely no doubt that
+'limited with' is the best proposal from a usability standpoint - there's
+less syntax and it fits well with the existing Ada model. But we don't know
+at this point if we can come up with a consistent set of rules for it, or it
+is even implementable. I fear that we may be 'poisoning the well' if we
+present this as a possibility now, and then are forced to give up on it in
+the future.
+
+In any case, it would be good if you would send out your examples in time
+for the rest of us to review them (as agreed in Padua). I've sent out mine
+for this very reason.
+
+> Many of us still believe this is one of the most important Ada 200Y
+issues.
+
+I still believe that, too. I'm just convinced that it is going to take two
+years to come up with an finished proposal for 'limited with' (because
+futzing with visibility rules requires extreme care), and we're going to
+have to keep at least one of the others open until we can do that. And I
+know I can't wait two more years to produce a meaningful upgrade to the Claw
+Builder, so I'm just going to have to implement something. And once I do
+that, there is little reason to change to something else (the same problem
+ACT has). So any decision here is going to be too little, too late.
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, March 26, 2003  4:57 PM
+
+> I guess I object to this attitude.  I think the "SIGAda"
+> participants did not consider this proposal, so it is
+> hard to say whether they would consider a stub in
+> a parent adequate "notice" of the existence of a
+> dependence.  In my view, it corresponds quite similarly
+> to the "notice" provided for subunits.
+
+I agree with Tuck, SIGAda is simply a source of input, not some official body
+with veto power, especially veto power over something they have not seen!
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, March 26, 2003  5:00 PM
+
+> But the same argument applies to the type stubs that you presented at
+> SIGAda, and we know for certain that those were not acceptable to those
+> participants.
+
+Even that is too strong. The folks at SIGAda did not do a careful analysis of
+the semantic issues, they simply expressed some wishes. It is fine to take the
+wishes into effect, but they should not be taken as vetoes. I think at this
+stage that the ARG is quite capable of making up its mind on the approach to
+follow, taking into account the input from SIGAda, but only taking it into
+account, not regarding it as proscriptive.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 26, 2003  8:54 PM
+
+Fine. But we discussed the SIGAda results extensively at Padua, and we
+agreed there that those concerns had to be addressed. (Thus the mildly
+clunky alternative 5 of type stubs). If we're going to ignore ARG decisions
+of less than 6 weeks ago, then I don't see how we're ever going to come to
+any conclusions on this topic. Because every time we reopen an issue, we get
+two new ideas to work out along with the (now 7) existing ones.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 26, 2003  9:17 PM
+
+In Padua I believe the ARG decided to pursue
+all three of the proposals (incomplete in child,
+type stub, and limited with). I don't see
+anything that has changed that. I realize
+not everyone liked all of the proposals, but
+at least initially we decided to consider them
+all on an even footing.  I did my wording
+assignment at least. ;-)
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, March 26, 2003  9:34 PM
+
+It's always nice if you can work with incremental decisions, but in a case like
+this, I suspect the whole thing has to be evaluated in final form as a package.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 26, 2003  10:07 PM
+
+I agree that was the final conclusion. But that is completely inconsistent
+with the smaller decisions made during the meeting. I don't know anymore
+what to make of them - perhaps we should just forget that four hours of
+discussion?
+
+Clearly, if we're just going to ignore those decisions, then I should make a
+realistic proposal based on the original type stubs. By following those
+decisions carefully, alternative 5 is not as clean or as usable as the
+original proposal.
+
+Now, what I see is that another alternative is essentially ignoring one of
+those decisions. That necessarily makes that alternative look 'cleaner' than
+the other ones which follow those decisions. And the reason given applies
+equally to the alternative 4 which we killed.
+
+That essentially makes the results of the 'users' at AdaUK a forgone
+conclusion. *I* don't like the way type stub looks in the examples *I*
+wrote -- who else is going to??? And *of course* type C.T looks better -- it
+doesn't meet a number of the criteria, so of course its simpler to look at.
+
+It's abundantly clear to me that I've been wasting my time on this issue -
+we're comparing apples to oranges. I can only hope that Pascal can make
+semantic sense out of 'limited with', because otherwise this problem will
+never be solved.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Thursday, March 27, 2003  5:26 AM
+
+> I agree that was the final conclusion. But that is completely inconsistent
+> with the smaller decisions made during the meeting. I don't know anymore
+> what to make of them - perhaps we should just forget that four hours of
+> discussion?
+
+I can accept that some people felt that the incomplete child type
+suffered from the same problem as the original type stub, in
+that it was not sufficiently visible and needed something in the
+context clause.  But not everyone felt that way, and for whatever reason,
+the decision was to pursue three proposals: limited with,
+type stub with context clause, and incomplete child type
+(without context clause).
+
+I promise that I am not trying to annoy you ;-).
+I'm just asking that you not prejudge the other proposals.
+I realize you have your own preferences.  That is natural,
+and that makes it harder to act also in the role of RM/AI editor.
+But you have generally been quite successful in the past
+in wearing multiple hats, and I am only asking you to try
+to continue that semi-split-personality on this one.
+I realize it may be frustrating at times if you personally think
+we are going down a wrong path.
+
+> Clearly, if we're just going to ignore those decisions, then I should make a
+> realistic proposal based on the original type stubs. By following those
+> decisions carefully, alternative 5 is not as clean or as usable as the
+> original proposal.
+>
+> Now, what I see is that another alternative is essentially ignoring one of
+> those decisions.
+
+The ARG conclusion was to pursue the incomplete child type
+without a context clause, for whatever reason.  I don't feel
+I am ignoring any decisions in doing so.  I realize it is
+possible to generalize the requirement imposed on the type
+stub to have a context clause, to apply it to the incomplete
+child type.  But at least there are some people who see the
+type stub and the incomplete child type as significantly
+different proposals, without having exactly the same issues.
+In particular, the type stub refers to an unrelated package,
+whereas the incomplete child type refers to a child/nested package.
+That distinction is sufficient for some people to reduce
+the need for context-clause visibility, and not for others.
+
+> ...
+> It's abundantly clear to me that I've been wasting my time on this issue -
+> we're comparing apples to oranges. ...
+
+You are definitely not wasting your time.  You have provided
+by far the best examples.  I realize it is frustrating if the
+examples make you believe there are other better ways of
+solving the problem, but at least for now, the ARG has chosen
+to pursue just these three, to try to keep us all sane.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Thursday, May 15, 2003  8:37 AM
+
+As you may have noticed, the AdaUK folks showed a surprisingly
+strong preference for the "type C.T" approach, followed by
+the "limited with."  Since I presented the material, part of
+this might be that my bias showed through, though I tried to
+be impartial (other observers there, such as John Barnes, might
+be able to comment on my success), and frankly, I like the
+"limited with" proposal from a user point of view.
+
+Some of the reasons cited for preferring the type C.T approach were
+that it seemed to be a smaller change that was easier to understand,
+and that it didn't introduce any new kinds of module interdependence.
+It also seemed to be more "structured" to some members of the audience.
+
+For what that's worth...
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, May 15, 2003  10:15 AM
+
+Yes, I noticed the results of the votes; but even so I still think
+strongly that "type C.T" is misguided.
+
+When explaining the (numerous) proposals that we considered for solving
+the mutually-dependent types problem, I have often felt a lot of
+discomfort, no matter what proposal was presented.  It seems to me that
+the notions of using something before having declared it, of naming a
+compilation unit without having a semantic dependence on it, etc., are
+extremely unpalatable to Ada users.  Of course we know that, whatever
+the details, any solution will have these properties, but the average
+Ada programmer has the feeling of somehow losing the safety of the
+language.  I believe that this explains for instance the request at
+SIGAda of naming the unit being forward-referenced in the context
+clause.
+
+It's quite difficult to judge a proposed language feature after a 15-mn
+presentation, in particular because there is a tendency to draw
+analogies with existing features, and such analogies may be invalid.  I
+remember that the first time I was told about child units, I was shocked
+that the parent didn't have to declare their children somehow.  Of
+course I realize now that this would annihilate the benefits of child
+units for extensibility, but it took me some time to swallow that model.
+
+From that perspective, type C.T is certainly easier to swallow as it is
+an extension of incomplete types completed in the body, and "limited
+with" looks odd with its partial compilation mechanism.  But I think
+that, when people have gotten used to it, they will be happier with
+"limited with" than with "type C.T".
+
+**************************************************************
+
+From: Arnaud Charlet
+Sent: Friday, May 16, 2003  10:30 AM
+
+I strongly agree with Pascal here, for the same reasons.
+Also since I was at the AdaUK meeting, I would say that indeed the
+three proposals were presented relatively rapidly (and there was clearly
+many other topics to cover).
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Friday, May 16, 2003  10:34 AM
+
+I agree with this position
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Friday, May 16, 2003  11:54 AM
+
+I second (fourth?) this opinion with one caveat.
+
+"limited with" does not work with generics (since the model doesn't allow
+looking in generic instantiations). Child units originally did not work with
+generics, and we were eventually forced by user pressure to add the
+(misguided in my view) generic child units. I fear that we're going to have
+the same reaction to "limited with". However, doing that would destroy the
+implementability of "limited with" for most compilers (because you'd have to
+process withs, meaning the entire dependency mechanism would have to be
+repeated). I personally can't think of how generics could be used in this
+problem, but I'm certain someone else can and will.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Friday, May 16, 2003  2:09 PM
+
+Here is an implementation model for the "incomplete type completed in
+a child" proposal (ai-00217-07).
+
+When parsing a type declaration, a child package prefix would
+be permitted.  If the declaration turns out to not be for
+an incomplete type, then a parse error would be indicated.
+
+The incomplete type semantic analysis routines would take
+the package prefix as an additional parameter.  If there is
+a non-null package prefix, then an "incomplete" package would
+be created, if not already existing, and the incomplete type
+would be introduced into the incomplete package.
+
+A list of all the incomplete packages in the current region would be
+maintained, along with an indication of which, if any, of
+the incomplete types came from incomplete_type_declarations
+occurring in the visible part.  If there is at least one, the incomplete
+package can only be "completed" by a public child or a nested package
+declared in the visible part; otherwise it can be completed
+by a private child or a nested package declared in the private part.
+
+If the incomplete package is completed by a nested package, all of
+the incomplete types are connected up to their completions; the completions
+must exist in the visible part of the nested package and be visibly tagged
+if so required; the nested package must be in the visible part if any of
+the incomplete types came from incomplete_type_declarations in the
+visible part.
+
+Once completed, the incomplete package is removed from the list of incomplete
+packages associated with the current region.  If there are any incomplete
+packages left on the list when the end of the private part of
+the current region is reached, then it is an error if the
+current region is not that of a (non-generic) library package.
+Presuming it is a non-generic library package, then this list is preserved
+in the symbol table of the library package, and an appropriate set
+of linker directives are created to indicate that the corresponding
+child packages are "needed" in any partition that includes the
+enclosing library package.
+
+When a child package is compiled, a check in the symbol table of the
+parent package is made to see if it corresponds to one of the
+incomplete packages needing completion.  If so it is checked
+that the child is a public child if so required, and that all
+of the needed completions exist in the visible part, and are
+visibly tagged if so required.
+
+When a name is found to denote an incomplete package, a check
+is made whether a library-unit renaming of the package has been
+mentioned in an in-scope "with" clause.  If so, the same view as
+that provided by the library-unit renaming is provided.  If not,
+then only the incomplete types in the incomplete package are
+visible.
+
+When a name is found to denote a package renaming that is not
+a library unit renaming, a check is made to see whether a corresponding
+incomplete package is visible, and not "overridden" by a library
+unit renaming.  If so, then the name provides a view of the
+incomplete package.  Otherwise if the name denotes an enclosing
+region, then the current view of this enclosing region is provided.
+Otherwise, the name provides a view of the visible part, augmented with
+any public children mentioned in in-scope with clauses.
+
+When dereferencing an access type whose designated type is an
+incomplete type, a check is made (as usual) to see whether the
+full type is visible.  If the incomplete type is declared
+in an incomplete package, then this involves seeing whether the
+full package_declaration is visible, either directly or via a
+library-unit renaming.  This is essentially the same check
+performed when traversing a non-library-unit package renaming,
+to determine whether the full view of the package should be
+provided.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, May 21, 2003  9:52 AM
+
+In implementation terms, the thing that bothers me more with the "type
+C.T" model is the syntax change.  All the rest should be feasible
+(although incomplete packages make me a bit nervous).
+
+Coming back to the syntax: changing the parser is of course trivial.
+However we depend on having a Diana representation that mimics the
+language syntax.  So the Diana representation would need to have a
+selected node as the as_id field of a type declaration.  Now there is a
+gazillion places in our compiler where we land on a type declaration and
+look at its as_id field.  All these places would become potential bugs
+because once in a blue moon we would find a selected node instead of an
+identifier, and we would query the wrong attributes.
+
+We have had the same issue in Ada 95 with child units, and I am still
+fixing bugs there.  References to types are as pervasive (or maybe more
+pervasive) than references to units, so I expect the same stream of
+bugs.  And this is an area of the language which will be less tested,
+because while most Ada 95 programs make pretty extensive use of child
+units, mutually-dependent types are only going to be used occasionally.
+
+I would like to hear if other implementers have the same concern or if
+this is somehow Rational-specific.
+
+**************************************************************
+
+From: Ed Schonberg
+Sent: Wednesday, May 21, 2003 10:51 AM
+
+In GNAT I don't expect the syntax to cause much problems. Once the
+declaration is processed, most references are to entities (symbol table
+entries, if you prefer) rather than to the original tree itself. My
+concerns are much more with issues of double visibility of incomplete types.
+In our original implementation of with_type clauses, if a full view of the
+type was in scope, the incomplete view was hidden and that was that. I
+suspect that the current limited_with proposal (as well as the others) does
+not permit such a simple model, but I have not examined the latest examples.
+
+Having to keep two views of packages (one limited, one not) would be an
+earthquake in the GNAT front-end, to be avoided at all costs.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, May 21, 2003  1:16 PM
+
+I haven't looked at this carefully yet (but I will). But I don't think that
+the syntax per-se is a major problem. My concern with it is that it will
+have to be supported on all type declarations (otherwise the syntax is
+ambiguous). Because of the way our compiler is structured, we'll open a new
+scope for the phony package. The net effect is that all type definitions
+will have to be prepared to close it, otherwise the error would cause a
+never-ending cascade of other errors. Which is a number of places, but the
+bugs would only occur in programs which used the feature, and which were in
+fact illegal. So I hardly can claim that that is a critical problem.
+
+I'm more concerned about dealing with the phony package needed, but that's
+shared between child type stubs and limited with.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, May 21, 2003  3:07 PM
+
+...
+> Having to keep two views of packages (one limited, one not) would be an
+> earthquake in the GNAT front-end, to be avoided at all costs.
+
+We are in agreement here, and both Randy and I had that same concern.  I
+believe that the latest write-up of all these AIs has the property that,
+when processing a given compilation unit, you only have visibility on
+one view of a given package, and which view you see is determined at the
+end of the context clause.  In some cases this is achieved by the
+limited view hiding the full view (that's to avoid ripple effects) but
+at any rate the two never meet.
+
+Doing otherwise would be an earthquake for us, too.
+
+**************************************************************
+
+From: Ed Schonberg
+Sent: Wednesday, May 21, 2003  3:45 PM
+
+This is most reassuring! I will have a more detailed evaluation of the
+difficulties that the remaining proposals might present for the GNAT
+front-end, before the ARG meeting in Toulouse.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, May 21, 2003 12:03 PM
+
+I don't know how "religious" you are about
+reflecting the syntax in the Diana, but it seems
+you could have an optional package-prefix attribute,
+rather than changing the ID to be a selected node.
+That would seem to be less likely to cause bugs,
+since you would only need to look at the package-prefix
+when reconstructing the source, and when initially
+deciding in which symbol table to place the incomplete
+type.
+
+But of course giving another implementor advice
+about their compiler is usually pretty hopeless...
+
+For what its worth, I would think the implementation of
+"type C.T" would be closer to GNAT's "with type P.T"
+implementation than would the implementation of
+"limited with."  Essentially "withing" a package P that
+contained a "type C.T" would be roughly equivalent
+to doing the "with P;" followed by "with type P.C.T;"
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, May 21, 2003  3:42 PM
+
+Of course, that crossed my mind, but I think it would cause trouble in
+some places.  For instance, when an error message includes a type name,
+it would be good to be able to point at the selected node, rather than
+screwing around trying to see if we are on a "type C.T" node.
+
+This being said, I think we would have to "reify" the incomplete package
+in the Diana for other reasons, so an option would be to point at the
+type declared in the incomplete package.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Friday, May 16, 2003  12:14 PM
+
+I did some more work on this to bring its handling of
+non-library-unit renamings in conformance with the
+direction established in the most recent "limited-with"
+version.
+
+[Editor's note: This is version /02 of the AI.]
+
+You will find additional wording for 3.10.1(11)
+and 8.5.3(4), and some additional discussion.
+
+The basic idea is that non-library-unit
+renamings don't provide more visibility than what you
+would see via some other name that denotes the same
+package.  On the other hand, by withing a library-unit
+renaming of a package, you get visibility on the
+full visible part (at least), and this in turn hides from all
+visibility the incomplete types introduced by "type C.T"
+(or limited with, in that proposal).
+
+The net effect is that all views of a package are the
+same, where non-library-unit renamings fall back
+to the visibility of other views already visible,
+while library-unit-renamings pull all views up to
+at least be the full visible part (plus any public
+children).
+
+I think this matches what happens with the
+most recent "limited with."  Basically it means
+that the presence of a visible non-library-unit
+renaming doesn't have any effect on the view of
+a package that is provided via some other name.  This might
+be considered eliminating another kind of
+undesirable "ripple" effect due to adding or
+removing a non-library-unit renaming in some random
+package that happens to be visible.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Monday, May 19, 2003  8:23 AM
+
+Tuck's AI has:
+
+>     incomplete_type_declaration ::=
+>       TYPE [package_identifier.]defining_identifier[discriminant_part]
+>         [is tagged];
+
+I am wondering how this proposal handles the following case:
+
+Say that you have a root library unit R, with two children C1 and C2,
+and that C1 has a child GC1 and C2 a child GC2.  Imagine moreover that
+all these packages declare types, and that you need to establish a
+circularity between R.C1.GC1 and R.C2.GC2.  This is not an unlikely
+situation.  Think of big class hierarchies where you have
+cross-dependences between (sub)classes.  Claw comes to mind.
+
+My first thought was that you would declare the incomplete types in R:
+
+	type C1.GC1.T;
+	type C2.GC2.T;
+
+However this has two problems:
+
+1 - It is forbidden by the syntax.
+2 - The incomplete types have to be declared "too high" in the
+hierarchy, in the sense that they are visible to R.C1 and R.C2 even
+though they are not needed there.  This is a situation that we try to
+avoid in Ada.
+
+I can't think of a solution to this problem that doesn't force you to
+screw up your unit hierarchy.  Maybe renamings can save the day, but it
+would be singularly awkward to have to resort to renamings in this
+simple case.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Monday, May 19, 2003  12:33 PM
+
+I'm not sure I see the problem.  Doesn't the following work:
+
+    package R.C1 is
+       type GC1.T;
+    end R.C1;
+
+    package R.C2 is
+       type GC2.T;
+    end R.C2;
+
+    with R.C2;
+    package R.C1.GC1 is
+       type T is ...
+       type GC2_T_Ptr is access C2.GC2.T;  -- acc-to-incomplete
+    end R.C1.GC1;
+
+    with R.C1;
+    package R.C2.GC2 is
+       type T is ...
+       type GC1_T_Ptr is access C1.GC1.T;  -- acc-to-incomplete
+    end R.C2.GC2;
+
+So long as the incomplete type and the full type can be declared in
+different compilation units, I think you can break the circularity.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, May 21, 2003  9:38 AM
+
+You're right, it works.  Somehow I was hoping for a solution based only
+on parent/child visibility, without with clauses.  Apparently that's not
+always possible.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, June 17, 2003  2:12 AM
+
+Here is the implementation report I promised at the last meeting for all
+three live AI-217
+proposals. I know that these are really late, but at least you'll have three
+days in which to read them. (Of course, if you're at Ada Europe already,
+that probably is really about 3 minutes. :-(
+
+---
+
+Implementation of AI-217 alternatives in Janus/Ada.
+
+This report looks at the implementation of AI-217 alternatives in Janus/Ada.
+Since it is specific to this compiler, it uses a lot of internal
+technology/terminology. The general conclusions should remain correct, however.
+
+----
+
+Type stubs, AI-217-05.
+
+----
+
+Type stubs would be implemented by taking advantage of the existing structure
+of types. Incomplete types have a separate type record (and thus Type_Ptr
+number - note to readers: Type_Ptrs are actually Integers in the "Fortran
+pointer" style); they are linked to their completing type via the Full_Def
+field. (This field is shared with private types, thus the name.) This field
+defaults to Null_Type (0), meaning "no type". If a type lookup finds a
+Full_Def of "no type", it stops at that point and returns the incomplete
+type (thus giving only the properties allowed of incomplete types).
+
+Fields would be added to provide the name of the completing type and
+completing package; these would have to be written into the .SYM file.
+Existing routines for handling identifier numbers and expanded names would
+be used.
+
+The units mentioned in limited with clauses would be added to a new, global
+list of identifiers, during the processing of with clauses. (This is very
+similar to what is done for other context clauses.)
+
+When a stub declaration is processed, a check would be made that the package
+named is in fact mentioned in a limited with (by consulting the limited with
+list). An incomplete type record would be created, with the stub package
+and type name filled in. Otherwise, this processing would be identical to
+that of a normal incomplete type; probably, the code to declare such a type
+will be shared.
+
+The .JRL file format would be extended to include a list of limited withs.
+This would be very similar to the existing list of regular withs (but without
+the time stamps). This would be used to make the post-compilation checks.
+
+As .SYM files are loaded during the processing of context clauses, a list will
+be created pointing to all of the type stubs. Once all of the context clauses
+have been processed (and thus, the complete symboltable [closure] is loaded,
+including any indirectly withed units), this list will be walked. Any type
+stubs whose completing type is in the symbol table because of a with clause
+or a library level renaming will have the Full_Def filed altered to point
+at the completing type. (In this case, most lookups will use the completing
+type - the thus the full properties of the type - for all purposes, including
+type matching). If the type is tagged, a similar operation would be done on the
+class-wide incomplete (class-wide types are separately expressed in the
+Janus/Ada type table).
+
+Similarly, when a type declaration is processed, the list will be searched
+for any type stubs for this type. If any are found, checks are made (that
+the type has the proper visibility and properties), and the Full_Def field
+of the incomplete type is set to point at the new type. (This will insure that
+the type is treated as complete within the scope of the full type.) Class-wide
+types for tagged types would also be handled. I am proposing using a simple
+list search here, as I don't expect this to be long (only a few stubs in each
+program) or a bottleneck. However, if profiling proves that it is a problem,
+the list could be organized by package names so that only stubs pointing at
+the current unit would be searched.
+
+The linker front-end (used in each of the different Janus/Ada linkers/binders)
+would be modified to implement the post-compilation checks. This mainly would
+involve looking at each unit that is mentioned in a limited with clause,
+insuring that it actually specifies a unit, and then looking in the with
+list for that unit to insure that the first unit (the one with the limited
+with clause) is withed.
+
+I believe that we've dropped the extra dereference stuff (it's still in the
+write-up), so I won't discuss implementing that.
+
+----
+
+Child Type stubs ("type C.T;"), AI-217-06.
+
+----
+
+These would be implemented very similarly to type stubs. However, the
+symbol table changes would be much more extensive.
+
+A new bit field ("ghost") would need to be added to packages to specify that it
+is not a real package (and thus cannot be used in "Use" clauses). This is
+mildly annoying, because we don't have any free bits in the current symbol
+table recond (thus, making it bigger).
+
+Similarly, a field would be added to the incomplete type record to
+specify the package name of the child; these would have to be written into
+the .SYM file. Existing routines for handling expanded names would be used.
+
+Processing a stub declaration is complicated by the new syntax. Janus/Ada
+is purely syntax-directed (in the sense of the Dragon book). The Janus/Ada
+grammar has a "hook" at the begining of the processing of a type declaration
+to create an empty symboltable record with the proper name. (Otherwise, that
+happens too late; there is nowhere to write the names of any components of
+the type, which are 'children' of the type name.) Because of the limitations
+of LALR(1) grammars (and the fact that we consider incomplete types to be
+"real" type_declarations), we would have to support the type C.T ... syntax
+for all types.
+
+If a type of the form of type C.T ... is seen, we would need to create a
+symboltable record for the package C (with the "ghost" bit set) at the current
+place in the symboltable, open a scope, and then create the dummy record for
+type T and open its scope. Of course, it is critical that the extra open scope
+be closed, so we would have to include the fact that this scope was opened on
+the parse stack. This would require a new kind of parse stack record
+[currently, we're just reusing the terminal stack item to pass the identifier
+up].
+
+Each production that closes a type definition would have to check this parse
+stack item and pop the scope if needed. There are roughly 7 such places (I
+didn't check this carefully).
+
+Other than this annoyance, a child type stub would be processed almost the same
+as a regular incomplete declaration. An incomplete type record would be
+created, with the child package name filled in. Otherwise, this processing
+would be identical to that of a normal incomplete type; probably, the code to
+declare such a type will be shared.
+
+As .SYM files are loaded during the processing of context clauses, a list will
+be created pointing to all of the type stubs. Once all of the context clauses
+have been processed (and thus, the complete symboltable [closure] is loaded,
+including any indirectly withed units), this list will be walked. Any type
+stubs whose completing type is in the symbol table because of a with clause
+or a library level renaming will have the Full_Def filed altered to point
+at the completing type. (In this case, most lookups will use the completing
+type - the thus the full properties of the type - for all purposes, including
+type matching). If the type is tagged, a similar operation would be done on the
+class-wide incomplete (class-wide types are separately expressed in the
+Janus/Ada type table).
+
+The .JRL file format would be extended to include a list of children
+required by child type stubs (I think we'll want a snappier name for this
+concept!). This would be very similar to the existing list of regular withs
+(but without the time stamps). This would be used to make the post-compilation
+check that the child unit is included in the closure of the partition.
+
+Similarly, when a type declaration is processed, the list will be searched
+for any type stubs for this type. If any are found, checks are made (that
+the type has the proper visibility and properties), and the Full_Def field
+of the incomplete type is set to point at the new type. (This will insure that
+the type is treated as complete within the scope of the full type.) Class-wide
+types for tagged types would also be handled.
+
+The linker front-end (used in each of the different Janus/Ada linkers/binders)
+would be modified to implement the post-compilation check. This mainly would
+involve looking at each unit that is listed as being required by a stub, and
+insuring that it actually is included in the partition.
+
+----
+
+Limited with, AI-217-07.
+
+----
+
+This is a very different beast.
+
+For each withable unit, we would define a new kind of symbol table file, the
+.LYM file (limited with file). This file would have the virtually the same
+format as the existing .SYM file (so we could use most of the existing
+code to read it), but would contain only packages and incomplete types for
+each type declared in the package.
+
+Following an idea suggested by Pascal, the .LYM files would use a hash value
+for obsoleteness checking. Thus, they can be recompiled as many times as
+necessary with changing the hash (presuming that no changes were made).
+
+An option would be added to the compiler to compile only an .LYM file. This
+option would cause the compiler driver to run a special second pass of the
+compiler after running the standard parsing pass. This special second
+pass would do very little other than create a skeleton symbol table and
+write it out as an .LYM file.
+
+A normal compilation of a unit would write the normal .SYM file, but also
+would write (or rewrite) the .LYM file. That insures that the .LYM file is
+in-sync with the object code; if the source code was changed after the .LYM
+was created, the compilation of that source must change the .LYM in order to
+cause a linker error. (We don't want to allow the stubbed type to be removed
+or changed from tagged to untagged without it being detected.)
+
+Normal compilation would always create an incomplete type record for each
+type declared in a spec. These records would always be completed (by setting
+Full_Def) in the .SYM file. But the records would be left incomplete (and
+would be the only type records in use) for the .LYM file.
+
+The .JRL format would be changed to include the .LYM hash for each unit, and
+the .LYM hash for 'self'. As with the .SYM timestamps, the .LYM hash would need
+to be identical for each occurrence of a unit. This check would be done in
+parallel with the existing .SYM timestamp checks in the linker front-end.
+
+If a limited with clause mentions a unit (and the unit is not otherwise loaded
+in the closure), the .LYM file would be loaded. This would provide a skelton
+of the package. Note that the .SYM includes all of the items declared in the
+.LYM; that includes the incomplete stub types. That means that if the closure
+includes a package which only had visibility on the .LYM, normal .SYM file
+loading type lookup will match those incomplete types to the equivalent ones
+(which are completed) in the full .SYM. Thus, we do not need to do anything
+special to load these types.
+
+This implementation will run into significant problems if we need to have
+limited views when the full view is available in the symboltable. The rules
+as contemplated appear to have this effect. Since Janus/Ada always loads the
+full closure, the full view is naturally available even when the package
+itself is not visible. Of course, Janus/Ada already has to stand on its head
+to hide the names (a sigificant source of bugs when code forgets to check
+whether a name is visible before using it). However, types themselves do not
+have visibility -- they are global constructs kept in a separate table. Thus,
+any time the full view is in the closure, the types would appear completed.
+Fixing this looks expensive -- either by adding visibility code to type lookup
+(that is, using visibility information to decide whether to follow the
+Full_Def field), or by somehow breaking the Full_Def field (by setting it to
+Null_Type). The problem with both of these approaches is that any code
+generated for the type will expect (since the full view is in the closure)
+that the full type is available. So substantial head-standing will be needed
+(presuming that code can be generated for these types; based on previous
+experience, I'd say that it is likely that it can, although I can't think of
+an example at 2 am).
+
+Another problem with this implementation is that type numbers are defined
+relative to the package that contains them. The loading algorithm assumes that
+the numbers for any particular package are contiguous. That won't be true of a
+.LYM package created from a full compile. In such a compile, the incomplete
+type records will be scattered about, with the various full definitions and
+subtypes between them. That is something that could not be changed, because the
+full compilation could not know what types and packages are yet to come in the
+compilation. We're clearly not going to be including the the full definitions
+and subtypes in the .LYM file; but I don't know if eliminating this invariant
+will cause major problems. [This was the last thing I thought of while doing
+this report, and it is too late to try to figure it out. Sorry.] An
+unappealing alternative would be to force the (separate) creation of a limited
+view first, load that into the symboltable, then compile the full view.
+However, this would require lots of extra work to eliminate the errors that
+would naturally occur when declaring a type or package that is already in the
+symboltable.
+
+Finally, a substantial reworking of the COrder compilation order tool will be
+needed. While the type stub proposal will need only very minor tweaking here
+(just to allow and ignore the limited with clause), and the child type stub
+proposal will need no tweaking at all, this would require a substantial
+rewrite.
+
+Pascal has suggested that the easiest way to handle this would be to simply
+generate .LYMs (limited views) for all specs in the program (in any order,
+the order cannot matter). However, processing a single file will take 1-2
+seconds (mostly because of the overhead of loading three programs and three
+data files). If you have a real program with 150 specs (such as the Janus/Ada
+compiler itself), that means that generating all of the .LYMs each time would
+take as much as an extra 300 seconds. This is way too long (think of adding
+that in front of every compile, especially after a user has made a one line
+change to some body). So it's clear that that approach will not work.
+
+Thus, we'll have to include a timestamp in the .LYM, and be prepared to compare
+it the timestamp of the source code. Then, any .LYMs out of date (or missing),
+will have to be regenerated. Note that this is a pure greater than check; the
+.LYM may be much newer than the source code, as it could be regenerated by
+later full compiles forced by normal obsoleteness.
+
+Doing so separately (as in Pascal's original suggestion, just limited to the
+units that have changed since the last compilation) would be the quick and
+dirty solution. But even that is likely to be too slow in some instances.
+However, a full solution (which would fully integrate the processing of
+limited withs into the compilation ordering decisions) is likely to be very
+expensive, especially as the code in question is rather "magic" as it is. So,
+we're probably stuck with the "limited compile everything that might have
+changed" approach.
+
+
+----
+
+Conclusions:
+
+Child type stubs and regular type stubs have similar implementation costs in
+Janus/Ada. However, child type stubs are more likely to cause problems, as they
+require changes in quite a bit more existing code (to handle making the use
+of "ghost" packages illegal in most contexts, and to handle the declaration
+[and "undeclaration"] of the "ghost" package in the first place.
+
+Limited with is quite a bit more expensive, both because a new, separate
+compiler pass is needed (with the attendant maintenance problems of having
+"separate but parallel" code), and because an entire new kind of symbol table
+file has to be devised and loaded. By keeping the formats similar to existing
+code, most of the existing code can be reused. Still, a number of problems
+with the straightforward solutions have been noted above (the type number
+invariants, and the visibility of complete types), which are likely to make
+this even more work, and may require reworking of parts of the compiler
+that don't seem to be "naturally" involved.
 
 **************************************************************
 

Questions? Ask the ACAA Technical Agent