CVS difference for ais/ai-50217.txt

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

--- ais/ai-50217.txt	2003/02/05 21:34:34	1.1
+++ ais/ai-50217.txt	2003/05/24 00:51:43	1.2
@@ -853,8 +853,2384 @@
 
 **************************************************************
 
-[Editor's note: Mail after the above time is not posted yet. That's
-58 messages as of this writing. Sorry.]
+From: Dan Eilers
+Sent: Monday, February  3, 2003  3:04 PM
+
+I like Pascal's "weak with" proposal a lot, although I'm not yet convinced
+we need to syntactically distinguish "weak with" from normal withs.
+
+I came to this conclusion by perhaps a slightly different route:
+
+1) we have a bunch of proposed syntax extensions to solve the circular
+   types problem, any of which are believed to be feasible to implement;
+
+2) essentially none of the proposed syntax extensions have any dual-use
+   benefit towards the solution of any other problem;
+
+3) we envision a tool that can automatically translate circular specs
+   written in other languages into the proposed new syntax;
+
+4) a similar tool could also translate Ada that allowed circular with's
+   into any of the proposed syntax extensions;
+
+5) given such a tool, the users would happily write Ada with circular
+   with's, and use the tool to create their package abstracts (in
+   whatever syntax);
+
+6) this could be made automatic.  When the compiler sees a "with" clause
+   for a unit that has not been compiled, instead of giving an error, it
+   can automatically invoke the translation tool to create the package
+   abstract, and then compile the abstract before continuing to compile
+   the original unit.
+
+6) this can be further optimized if desired so the translation tool is
+   integrated into the compiler, rather than needing to be a stand-alone
+   tool.
+
+
+Notes:
+
+Recursive subprogram calls don't use different syntax than non-recursive
+ones, so ideally recursive with's wouldn't either.
+
+We need to address the elaboration order concerns, but presumably that
+is more naturally done with elaboration pragmas than with different
+syntax for "with" clauses.
+
+I still think there is some possible dual-use synergy with the separate
+private issue.  As Tuck corrected me, you can't just put the private
+part in a separate file.  So instead of "private is separate" you would
+have to say "the remainder of this package is separate".  A "with" clause
+on such a package would continue to see both the root and the subunit.
+A "with p'abstract" would see only the root.  I believe such new syntax
+would at the same time solve the separate private issue and the circular
+types issue, and perhaps also the separate constants issue.
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Monday, February  3, 2003  4:07 PM
+
+> 6) this could be made automatic.  When the compiler sees a "with" clause
+>    for a unit that has not been compiled, instead of giving an error, it
+>    can automatically invoke the translation tool to create the package
+>    abstract, and then compile the abstract before continuing to compile
+>    the original unit.
+
+That won't do at all for a source based compilation system, there is no
+concept of "a unit that has not been compiled". One of the critical
+guarantees in GNAt is that order of compilation NEVER affects the results
+and we would strenuously object to a change in semantics which would
+destroy this guarantee. For one thing it means that the meaning of a
+program is not fully conveyed by its sources, and that is pragmatically
+and philsophically unacceptable.
+
+**************************************************************
+
+From: Robert A. Duff
+Sent: Monday, February  3, 2003  4:16 PM
+
+Yes, I agree.
+
+This makes me think that these tools that translate from other languages
+(or create bindings thereto, I guess) ought to make sure that their
+generated Ada code doesn't do anything at elab time -- at least in the
+presence of cycles.  That seems achievable, and simpler than having user
+options to specify elab order.
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Monday, February  3, 2003  4:25 PM
+
+Note that another objection is that this means that automated tools for
+determining the compilation order would have to do semantic analysis.
+
+**************************************************************
+
+From: Robert A. Duff
+Sent: Monday, February  3, 2003  4:12 PM
+
+Dan Eilers wrote:
+
+>...
+> 3) we envision a tool that can automatically translate circular specs
+>    written in other languages into the proposed new syntax;
+
+Right, but those languages typically don't have the same
+elaboration-order issues that Ada does.
+
+> 4) a similar tool could also translate Ada that allowed circular with's
+>    into any of the proposed syntax extensions;
+
+True, but...
+
+> 5) given such a tool, the users would happily write Ada with circular
+>    with's, and use the tool to create their package abstracts (in
+>    whatever syntax);
+
+I fear that such a tool would be inherently error prone.  Suppose we
+have package specs A and B, which 'with' each other.  The tool would
+have to choose which one to elaborate first, and it might guess wrong.
+I think it's better to let the user specify the order via "limited
+with".
+
+Besides, now that I think about it, how would this tool work?  "Limited
+with" implies a very restricted usage of the imported package.  The tool
+would have to check that such restrictions are obeyed before turning a
+"with" into a "limited with".
+
+> 6) this could be made automatic.  When the compiler sees a "with" clause
+>    for a unit that has not been compiled, instead of giving an error, it
+>    can automatically invoke the translation tool to create the package
+>    abstract, and then compile the abstract before continuing to compile
+>    the original unit.
+
+Users normally don't compile.  They run a build tool, which
+automatically compiles everything that needs to be compiled, in some
+order that is not easily known to the programmer.  It seems error-prone
+to have the semantics depending on what happens to have already been
+compiled.  That's true even if the user bypasses the build tool and
+explicitly invokes the compiler in some order.
+
+> 6) this can be further optimized if desired so the translation tool is
+>    integrated into the compiler, rather than needing to be a stand-alone
+>    tool.
+>
+>
+> Notes:
+>
+> Recursive subprogram calls don't use different syntax than non-recursive
+> ones, so ideally recursive with's wouldn't either.
+
+True, but this case seems different to me.
+
+If I see:
+
+    with B;
+    package A is ...
+
+I currently know for certain that the spec of B is elaborated before A.
+I don't have to go looking at B to see that that's true.  I don't think
+we should break that property.
+
+> We need to address the elaboration order concerns, but presumably that
+> is more naturally done with elaboration pragmas than with different
+> syntax for "with" clauses.
+
+I don't think the existing pragmas can be used for this purpose.
+Suppose the cycle is "A with's B with's C with's A".  Adding a pragma
+Elaborate in A pointing to B doesn't work, because it's not transitive
+to C.  Adding Elaborate_All doesn't work, because that would require A
+to be elaborated before itself (because it's transitive).
+
+So we would have to add a new pragma to explicitly break one link in the
+cycle:
+
+    with X; pragma Don't_Elaborate(X); -- ;-)
+
+But that means precisely what "limited with X;" would mean.
+
+Elaboration pragmas were a mistake in the first place.  They were added
+late in the game to Ada 83 to solve the "Brosgol anomalies".  We added
+more pragmas in Ada 95, and I'm afraid we botched the job -- we *still*
+didn't solve the problems.  I suggest we avoid compounding the mistake
+of using pragmas to control elaboration.
+
+Furthermore, "limited with X" implies various restrictions on the use of
+X -- you can only refer to types in X, and they are all incomplete (or
+access to incomplete).  Pragmas shouldn't be in *that* business.
+
+> I still think there is some possible dual-use synergy with the separate
+> private issue.  As Tuck corrected me, you can't just put the private
+> part in a separate file.  So instead of "private is separate" you would
+> have to say "the remainder of this package is separate".  A "with" clause
+> on such a package would continue to see both the root and the subunit.
+> A "with p'abstract" would see only the root.  I believe such new syntax
+> would at the same time solve the separate private issue and the circular
+> types issue, and perhaps also the separate constants issue.
+
+Perhaps, but I skept.  I'm having trouble seeing the separate-private
+issue as anything more than a simple textual translation, with no
+run-time consequences whatsoever.  I haven't seen a fully worked-out
+proposal that solves both problems...
+
+P.S. This discussion makes me think of another observation.  If a given
+cycle contains two or more "limited with"s, then elaboration order will
+presumably be implementation defined.  I suppose that's OK -- if you
+care, you can break the cycle with just one "limited with", and use
+normal "with" for the rest.
+
+**************************************************************
+
+From: Dan Eilers
+Sent: Monday, February  3, 2003  6:23 PM
+
+Bob Duff wrote:
+
+> Perhaps, but I skept.  I'm having trouble seeing the separate-private
+> issue as anything more than a simple textual translation, with no
+> run-time consequences whatsoever.  I haven't seen a fully worked-out
+> proposal that solves both problems...
+
+OK, here's the canonical example worked out:
+
+-- Note: with'ing package P creates a semantic dependency on all subunits
+-- such as P.Extension declared in P, and makes all declarations in
+-- P.Extension visible as if they were declared directly in P.
+
+-- with'ing P'abstract does not create a semantic dependency on subunits
+-- such as P.Extension, and does not make p.Extension's declarations visible,
+-- and does not allow declaring objects of types from P whose full type is
+-- deferred to P.Extension.
+
+    package Employees is
+        type Employee is private;       -- completed in subunit
+        type Emp_Ptr is access all Employee;
+        package Extension is separate;
+    end Employees;
+
+    package Departments is
+        type Department is private;
+        type Dept_Ptr is access all Department;
+        package Extension is separate;
+    end Departments;
+
+    with Departments'abstract;
+    separate(Employees)
+    package Extension is
+        type Emp_Ptr is access all Employee;
+        procedure Assign_Employee(E : access Employee;
+                                  D : access Departments.Department);
+        function Current_Department(D : access constant Employee) return
+            Departments.Dept_Ptr;
+    private
+        type Employee is record
+           dept: Departments.Dept_Ptr;
+        end record;
+    end Extension;
+
+    with Employees'abstract;
+    separate(Departments)
+    package Extension is
+        type Dept_Ptr is access all Department;
+        procedure Choose_Manager(D : access Department;
+                                 Manager : access Employees.Employee);
+    private
+        type Department is
+           mgr: Employees.Emp_Ptr;
+        end record;
+    end Extension;
+
+
+For the "private is separate" problem, instead of:
+
+    package p is
+      ...
+    private is separate;
+    end P;
+
+you would have:
+
+    package p is
+      ...
+    private
+      package extension is separate;
+    end;
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Monday, February  3, 2003  4:27 PM
+
+Robert A Duff wrote:
+>
+> > This brings me directly to the second gotcha.  I think it is clear (at
+> > least to me) that for this to be useful, the limited view of an access
+> > type has to be an access type.  But there have to be limits on how this
+> > access type can be used in the limited view.
+>
+> Can't we say that it's an access type whose designated type is
+> incomplete?  And then you can't do things like X.all.
+
+You are starting to give me the "willies."
+We will have to process rep-clauses if the access type
+in a limited-with-ed package is not itself considered an
+incomplete type.
+
+If we want a non-incomplete access type, then I think we need to
+declare it in a non-limited-withed place.  Hence,
+this doesn't solve the problem associated with proliferation
+of access type declarations.
+
+And I do still like that "type C.T;" ;-).
+(what a pain I can be...)
+
+> >...  (Translation, if you
+> > create a type with a component of  (a limited view of) an access type,
+> > then it is illegal to have a non-null default value for a component of
+> > that type.  Other rules are possible.)
+>
+> I think you can't have an allocator (as a default or anything else),
+> but I don't see why it couldn't be a function call that happens to
+> return the access type.  Perhaps an example?
+
+Gack.  You are back to requiring that the limited-with-er chooses
+a representation for a type that it isn't declaring.
+In this era where we are on the cusp of moving from 32-bit pointers
+to 64-bit pointers, I fear that rep clauses on access types may
+be more common, rather than less.
+
+
+
+By the way, I have discovered (remembered?) that we have a "loose parser"
+built into our compiler.  It's job is to do lookahead where strict one-pass
+semantic analysis is difficult.  For example, it scans bodies looking for
+labels, and then inserts them at the "begin."  It scans generic formal
+parts looking ahead until it finds out in what parent unit the generic
+is declared, so it can interpret the names in the formal part properly.
+In any case, this is a full, but very stupid and quite "lax" parser.
+It could probably build up a tree of package and type names.  It could
+certainly not make any semantic sense out of a rep clause, and since the
+rep clause could use named numbers declared in other packages
+(e.g. "for My_Acc_Type'Size use Targ_Dep.Size_Of_Access_Type;"),
+it really couldn't be made to work.
+
+So if we consider this limited-with approach, I think we want to make
+minimal assumptions about syntactic processing, and zero assumptions
+about representation processing, of the items in the limited-withed unit.
+
+I also agree with Bob that the less said about the way the magic
+happens the better.  Clearly there will be some kind of compilation
+dependence on the source of the limited-withed unit, but the key point is there
+is no semantic or elaboration dependence on the unit.  It seems fine if
+the source of the unit is edited "after" something that mentioned it in a limited-with
+clause is compiled, but before the unit itself is compiled.  But of course,
+whenever the source is changed, everything that has a compilation-dependence
+on it will probably need to be recompiled prior to linking.
+
+The "trick" that makes it all possible is that the *fully compiled* representation of
+both units in a cyclic dependence depend on the *source text* of both units.
+The fully compiled representations don't both depend on the others fully compiled
+representation.  Of course, there may be intermediate forms between source
+text and fully compiled representations, but those don't need to be mentioned.
+And the other important point is there is no transitive compilation dependence
+if the unit mentioned in a limited-with clause itself depends on other
+units, via withs or limited-withs.
+
+Presumably, mutual inlining, if supported, requires similar tricks.
+
+Other observations if we consider limited-with:
+
+I suppose to be consistent, we should interpret "limited with P.Q.R;"
+as equivalent to "limited with P, P.Q, P.Q.R;".  Also it seems clear
+that limited with is ignored if there is a non-limited with for the
+same unit.
+
+Another important point is that if a unit is mentioned in a limited with
+clause, it is a *post*-compilation rule that the unit be semantically
+(or even syntactically) correct, as opposed to a legality rule.  When compiling
+the unit having the limited with, the compiler may of course check some part of
+this post-compilation rule early (provided of course it doesn't create an inappropriate
+semantic dependence), but an ACATS test should not require that any particular
+errors in the unit mentioned in the limited-with be identified at this time.
+Certainly compilers will vary in how picky is the parser that they
+use to implement limited with, especially given that Ada's "syntax"
+rules slop over into semantic processing fairly frequently, due to the
+lack of direct LALR(1) parsability.
+
+The only requirement should be that *if* the unit is semantically correct,
+then you can safely mention it in a limited-with.  But you cannot rely
+on the compiler detecting all (or any) errors in a unit mentioned in a limited-with,
+though it can be arbitrarily picky about it.  Eventually, prior to linking,
+it will require that the unit exist and be semantically correct.  This
+means that when a unit mentions a second unit in a limited-with
+clause, the second unit is "needed by" the first unit, in the
+sense of 10.2(2-6).
+
+The above is related to 10.1.4(5) which says:
+
+   When a compilation unit is compiled, all compilation units upon which
+   it depends semantically shall already exist in the environment...
+
+We could change this to "... upon which it depends semantically or
+which it mentions in a limited_with_clause shall ..." and it would still be OK.
+
+However, 10.1.4(6) which says:
+
+   The implementation may require that a compilation unit be legal before
+   inserting it into the environment.
+
+is too strict.  It could be changed to:
+
+   The implementation may require that a compilation unit satisfy the Syntax
+   Rules before inserting it into the environment.  The implementation may
+   require that a compilation unit be legal before allowing it to be mentioned
+   in a with_clause other than a limited_with_clause.
+
+**************************************************************
+
+From: Robert A Duff
+Sent: Monday, February  3, 2003  5:17 PM
+
+Tucker wrote:
+
+> Robert A Duff wrote:
+> > Can't we say that it's an access type whose designated type is
+> > incomplete?  And then you can't do things like X.all.
+>
+> You are starting to give me the "willies."
+> [...description of willies]
+
+OK, I withdraw my suggestion.
+
+But it seems like whatever solution to the mutual recursion problem we
+choose, we really need to solve the problem of proliferation of silly
+type conversions.  Otherwise, these proposals will be nearly unusable.
+
+That is, there ought to be an *implicit* conversion between access types
+in the "safe" cases.  I know we discussed that before.  Is it part of
+any of these proposals, or is it a separate AI?  I seem to recall that
+it might be wrapped up with other access-type issues, like allowing "not
+null" constraints, and access-to-constant parameters.
+
+> And I do still like that "type C.T;" ;-).
+> (what a pain I can be...)
+
+That's a fine solution, IMHO.  Your earlier e-mail about
+mutually-recursive types being part of the same abstraction
+makes me comfortable with the idea of tying the solution to
+child packages.  (See, it *is* possible to convey sensible information
+about purely aesthetic concerns.  ;-))
+
+But I would choose the "limited with" idea, unless it is considered too
+hard to implement.
+
+> Presumably, mutual inlining, if supported, requires similar tricks.
+
+And mutual generic instantiation?
+
+> Other observations if we consider limited-with:
+>
+> I suppose to be consistent, we should interpret "limited with P.Q.R;"
+> as equivalent to "limited with P, P.Q, P.Q.R;".  Also it seems clear
+> that limited with is ignored if there is a non-limited with for the
+> same unit.
+
+Or any other "strong" dependence, such as child upon parent.
+
+I guess "strong dependence", as I've been calling it, is exactly the
+same notion as "semantic dependence".
+
+> Another important point is that if a unit is mentioned in a limited with
+> clause, it is a *post*-compilation rule that the unit be semantically
+> (or even syntactically) correct, as opposed to a legality rule. ...
+
+I don't see the need for any verbiage in the RM about this point.
+And I don't see how this differs (in theory) from normal with_clauses.
+(It might differ in practise, depending on how the compiler actually
+works.)
+
+I mean, if B says "with A;", there is currently no rule saying "A shall
+be legal."  A compiler could properly say nothing more than "no errors
+found in B", even if there are errors in A.  (That would be unfriendly,
+IMHO.)  Of course, sometime before running the program, A must be
+compiled, and the errors detected.
+
+> ...This
+> means that when a unit mentions a second unit in a limited-with
+> clause, the second unit is "needed by" the first unit, in the
+> sense of 10.2(2-6).
+
+Yes, that's a key point.  It might be that the second unit is mentioned
+*only* in limited_with_clauses, in which case there are no elaboration
+dependendences upon it, but it still needs to be included in the
+program, and elaborated at some point (possibly very late).
+
+> The above is related to 10.1.4(5) which says:
+>
+>    When a compilation unit is compiled, all compilation units upon which
+>    it depends semantically shall already exist in the environment...
+>
+> We could change this to "... upon which it depends semantically or
+> which it mentions in a limited_with_clause shall ..." and it would still be OK.
+
+I don't see any need to change this, given that "existing in the env" is
+such a vague concept.  In GNAT, it just means the file is sitting there
+on the disk.  In AdaMagic, it just means it is sitting there on the disk
+and has been "registered".  Registration only does minimal syntax
+checking.  In Rational's compiler, it means something more.
+
+> However, 10.1.4(6) which says:
+>
+>    The implementation may require that a compilation unit be legal before
+>    inserting it into the environment.
+>
+> is too strict.  It could be changed to:
+
+I don't see why.  The GNAT model does not take advantage of this
+permission.  The permission is there for the benefit of compilers like
+Rational, where "inserting" involves running the compiler, and therefore
+checking various rules.  I suppose AdaMagic takes partial advantage of
+this permission, since insertion involves some small amount of syntax
+checking.
+
+But why should we care how much checking is done on B before "limited
+with B" can be swallowed by the compiler?  If B is illegal, the compiler
+can process "limited with B" if it likes, or (if it happens to notice
+the illegality), it can complain that "limited with B" is nonsense.
+It doesn't matter whether the illegality is syntactic or semantic.
+
+>    The implementation may require that a compilation unit satisfy the Syntax
+>    Rules before inserting it into the environment.  The implementation may
+>    require that a compilation unit be legal before allowing it to be mentioned
+>    in a with_clause other than a limited_with_clause.
+
+I see no need for this added complexity.  And it could be a burden -- if
+the compiler chooses to implement some simple Legality Rule in the
+parser, that should be allowed.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Monday, February  3, 2003  6:20 PM
+
+Robert A Duff wrote:
+> Tucker wrote:
+> ...
+
+>>The above is related to 10.1.4(5) which says:
+>>
+>>   When a compilation unit is compiled, all compilation units upon which
+>>   it depends semantically shall already exist in the environment...
+>>
+>>We could change this to "... upon which it depends semantically or
+>>which it mentions in a limited_with_clause shall ..." and it would still be OK.
+>
+> I don't see any need to change this, given that "existing in the env" is
+> such a vague concept.  In GNAT, it just means the file is sitting there
+> on the disk.  In AdaMagic, it just means it is sitting there on the disk
+> and has been "registered".  Registration only does minimal syntax
+> checking.  In Rational's compiler, it means something more.
+
+I think we need to say *something* about the requirements
+on a unit mentioned in a limited-with clause.  Why not say
+it must exist in the environment?  As you said, that is
+pretty vague.  If there are no requirements on it, then
+the implementation has no place to "hang" whatever requirements
+it really does have.  It can't just invent requirements that
+don't exist.  But it can say, "as far as our implementation
+is concerned, that unit doesn't exist in the environment,
+so we refuse to compile the limited-with for it."
+
+>>However, 10.1.4(6) which says:
+>>
+>>   The implementation may require that a compilation unit be legal before
+>>   inserting it into the environment.
+>>
+>>is too strict.  It could be changed to:
+>
+> I don't see why.
+
+Again, we need a place for the implementation to "hang"
+its requirements.  We have given them the first handle,
+by allowing them to require existence.  Now we are
+giving them the second handle, allowing them to impose
+certain other requirements on the unit.  They *clearly*
+can't impose complete legality requirements, if the
+units are inserted one at a time, since there is no
+order of insertion that would allow that.
+
+> ...
+> The GNAT model does not take advantage of this
+> permission.  The permission is there for the benefit of compilers like
+> Rational, where "inserting" involves running the compiler, and therefore
+> checking various rules.  I suppose AdaMagic takes partial advantage of
+> this permission, since insertion involves some small amount of syntax
+> checking.
+>
+> But why should we care how much checking is done on B before "limited
+> with B" can be swallowed by the compiler?  If B is illegal, the compiler
+> can process "limited with B" if it likes, or (if it happens to notice
+> the illegality), it can complain that "limited with B" is nonsense.
+> It doesn't matter whether the illegality is syntactic or semantic.
+
+You are missing the point.  I am simply *allowing* compilers
+to impose requirements, but only up to a point.
+Without such verbiage, I don't believe compilers would be
+allowed to impose any requirements.
+
+I suppose you could argue all of this verbiage is unnecessary
+already, but since we felt the need to put it there in the
+first place, and we presumably aren't going to take it out,
+I believe it needs to be updated to *allow* compilers to impose
+certain requirements on limited-with'ed units.  But I definitely
+don't want to force them to impose these requirements
+(and I don't think my suggested wording does that).
+
+>>   The implementation may require that a compilation unit satisfy the Syntax
+>>   Rules before inserting it into the environment.  The implementation may
+>>   require that a compilation unit be legal before allowing it to be mentioned
+>>   in a with_clause other than a limited_with_clause.
+>
+> I see no need for this added complexity.  And it could be a burden -- if
+> the compiler chooses to implement some simple Legality Rule in the
+> parser, that should be allowed.
+
+I'm not sure what we are discussing any more, since you
+don't seem to think that the unit even need to exist
+in the environment to be mentioned in the limited-with
+clause.  I think we need to *allow* implementations
+to impose some requirements, and we might as well tie
+it to the notion of "exist" in the environment.
+*If* we tie it to that notion, we want to be sure that
+limited-with can in fact be used.  That seems to mean
+that you must be able to insert units into the environment
+before they can be (fully) compiled, strictly for the purposes
+of doing a "limited with" of them.
+
+Why don't you suggest some wording so we actually
+have an alternative to consider?
+
+**************************************************************
+
+From: Robert A Duff
+Sent: Monday, February  3, 2003  6:46 PM
+
+Tucker wrote:
+
+> I think we need to say *something* about the requirements
+> on a unit mentioned in a limited-with clause.  Why not say
+> it must exist in the environment?  As you said, that is
+> pretty vague.  If there are no requirements on it, then
+> the implementation has no place to "hang" whatever requirements
+> it really does have.  It can't just invent requirements that
+> don't exist.  But it can say, "as far as our implementation
+> is concerned, that unit doesn't exist in the environment,
+> so we refuse to compile the limited-with for it."
+
+OK, you have convinced me on that point.  But as to 10.1.4(6):
+
+> Again, we need a place for the implementation to "hang"
+> its requirements.  We have given them the first handle,
+> by allowing them to require existence.  Now we are
+> giving them the second handle, allowing them to impose
+> certain other requirements on the unit.
+
+But 10.1.4(6) as is already gives sufficient permission.
+Your proposed change gives *less* permission.
+I claim there is no need to be more restrictive (on implementations),
+and that being more restrictive requires more complex RM wording.
+
+10.1.4(6) as is allows compilers to refuse to deal with "limited with X"
+on an illegal X.  That is sufficient permission.  If X is in the env,
+and is legal, the compiler must deal with "limited with X", because the
+only permission to refuse to admit X into the env is if it's illegal.
+
+>  They *clearly*
+> can't impose complete legality requirements, if the
+> units are inserted one at a time, since there is no
+> order of insertion that would allow that.
+
+There is no requirement that units are inserted one at a time (and in
+fact they are not, in AdaMagic).  Hence, it is not "*clearly*" true that
+they can't impose legality requirements.
+
+Your wording for 10.1.4(6) does not allow a compiler to impose such
+legality requirements.  I think that's overspecification, and could be
+an implementation burden.  For example, it is reasonable to implement
+some legality rules in the parser, and some compilers do that.
+One might wish to run the parser on X when seeing "limited with X".
+Your wording would disallow such an implementation.
+
+Imagine a front end structured as three phases:
+
+    1. Parse and build syntax tree.
+    2. Walk tree, build symbol table nodes for explicit declarations,
+       collect a list of all type decls, and check *some* legality
+       rules.
+    3. Overload resolution, and check the rest of the legality rules.
+
+The "limited with" wants that list of type decls from phase 2.
+But your wording seems to forbid phase 2 from printing any error
+messages, because they're not syntax errors.
+
+> I'm not sure what we are discussing any more, since you
+> don't seem to think that the unit even need to exist
+> in the environment to be mentioned in the limited-with
+> clause.
+
+I backed off on that part.
+
+>...  I think we need to *allow* implementations
+> to impose some requirements, and we might as well tie
+> it to the notion of "exist" in the environment.
+> *If* we tie it to that notion, we want to be sure that
+> limited-with can in fact be used.  That seems to mean
+> that you must be able to insert units into the environment
+> before they can be (fully) compiled, strictly for the purposes
+> of doing a "limited with" of them.
+>
+> Why don't you suggest some wording so we actually
+> have an alternative to consider?
+
+OK, I propose changing 10.1.4(5) in the way you suggested, and leaving
+10.1.4(6) as is.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Monday, February  3, 2003  7:02 PM
+
+Robert A Duff wrote:
+ > ...
+> OK, I propose changing 10.1.4(5) in the way you suggested, and leaving
+> 10.1.4(6) as is.
+
+I suppose there is an unwritten rule that there
+must be some way for two packages with cylic
+dependence to be inserted into the environment.
+Clearly if the "insertion" process requires legality,
+and you can only insert one unit at a time,
+there is a problem.  Either the compiler
+must allow simultaneous multiple-file insertion
+(that sounds like it might be illegal in Nebraska ;-),
+or it must allow units that are not yet demonstrably
+legal to be inserted.
+
+**************************************************************
+
+From: Robert A Duff
+Sent: Monday, February  3, 2003  7:14 PM
+
+Don't you think it's OK to leave that rule unwritten?
+I mean if that's a hole, it's already a hole.
+
+If I have some legal code, I must be able to insert it into the env
+*somehow*, since there's no permission for the implementation to refuse
+legal code.  The fact that the implementation is incapable of
+determining whether it's legal seems irrelevant.  *I* know it's legal.
+
+I think you're worrying overmuch about implementation issues (in
+considering RM wording).  Legal code must be accepted.  Therefore, code
+must be accepted if the compiler does not (yet) know whether it's legal.
+The compiler can only refuse if it can *prove* it's illegal.  Make
+sense?
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Monday, February  3, 2003  8:33 PM
+
+After thinking more about this, I think we need
+to make some change to the wording of 10.1.4(6).  It really
+doesn't make any sense if we change 10.1.4(5) as proposed.
+We seem to agree that this sentence is primarily for
+non-source-based compilers, where the only way to insert a
+unit into the environment is by processing it in some way.
+But it is exactly those compilers that will have to change to
+support limited-with.  They *cannot* require legality of all
+units inserted into the environment, if we have just
+changed 10.1.4(5) to require that the unit mentioned in
+a limited-with must already *be* in the environment.
+
+I think we should say something closer to this:
+
+   Before inserting a compilation unit into the environment,
+   the implementation may require that it obey all the Syntax
+   Rules, and any other rules that it can check given
+   what other units already exist in the environment.
+
+> ...
+> I think you're worrying overmuch about implementation issues (in
+> considering RM wording).  Legal code must be accepted.  Therefore, code
+> must be accepted if the compiler does not (yet) know whether it's legal.
+> The compiler can only refuse if it can *prove* it's illegal.  Make
+> sense?
+
+No. ;-).
+
+I think either we should make 10.1.4(6) completely
+implementation-defined, or replace it with something
+that reflects the problem that non-source-based
+compilers will have with limited withs, since we
+know that 10.1.4(6) was crafted specifically for
+their needs.
+
+Remember, this is in the section called "implementation
+permissions" so it is specifically talking to implementors,
+not users, and it is specifically talking about implementation
+issues, not abstract semantic issues.
+
+**************************************************************
+
+From: Robert A Duff
+Sent: Monday, February  3, 2003  7:06 PM
+
+Pascal,
+
+This "weak with" ("limited with") thing is your proposal, but if you
+like, I might be willing to work out the RM wording tomorrow (Tuesday).
+This idea seems to be gaining favor, and if it's to be chosen, I don't
+really want that to take 17 more ARG meetings.  Producing wording now
+might speed things up.
+
+On the other hand, if folks think it's too hard to implement, please say
+so before I waste my time.
+
+Should I do it?
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:21 AM
+
+It would be very useful if you did that.  You are much more competent than me at
+crafting RM wording, and furthermore I don't think I would have time to do that
+between now and the meeting.
+
+Since there seems to be some interest for the idea, it would be good to have a
+precise proposal on the table to discuss it.  Experience has proven that
+discussing an AI without an initial write-up is sterile.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Monday, February  3, 2003  8:35 PM
+
+I'm not Pascal, but I'd suggest going ahead and writing up the wording. I'm
+having a hard time getting a handle on this proposal, and I'm sure that
+would help. OTOH, since it is a complete start from scratch, it's going to
+take 17 meetings to get it right in any case. At most, you can reduce that
+number by one. :-)
+
+> On the other hand, if folks think it's too hard to implement, please say
+> so before I waste my time.
+
+At the moment, I think it's too hard to implement (given that type stubs are
+expected to take 4 hours of work; this would be more like 4 weeks). But that
+may be irrelevant. More important is that I don't see any way, within the
+current design of Janus/Ada, to implement something like this.
+
+The problem is with the obsoleteness check. Janus/Ada uses a serial number
+created from the time stamp of the symbol table file created for a library
+unit for checking. Also, the Janus/Ada compiler knows nothing about source
+files other than the one it is compiling at the moment. (Other tools are a
+bit smarter, but the compiler does not use that information itself.) It only
+knows about symbol table files.
+
+One presumes that you'd have a new kind of symbol table file that held a
+'lightly' compiled package spec for limited withs. And you'd use the time
+stamp of that file to create the serial number for obsoleteness checking.
+Clearly, when you 'really' compiled the spec, the new kind of package spec
+would have to be updated (otherwise, it wouldn't necessarily match the
+source file, because the source file could have been edited). But that would
+necessarily change the serial number, and then the links would fail. And
+there would be no way to avoid the problem.
+
+Given that there is no reliable way to determine if a file has been changed
+(file time stamps are too crude, often changing when nothing actually is
+changed, and aren't kept to enough accuracy on Windows), I don't see any way
+to implement this. The compiled=changed model works fine for Ada 95, but is
+a complete failure for limited with. Essentially, you have to adopt a
+source-based model, and that is a major change.
+
+This also has a giantic impact on build tools. They'd have to be able to
+process this new clause and come up with an appropriate order in the face of
+cycles. Of course, tools just punt if that happens now.
+
+It may be I just haven't thought about it enough. But I have a lot of things
+that I need to do before I leave for the meeting, and thinking about this
+isn't high on the list.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Monday, February  3, 2003  8:53 PM
+
+Randy's comments make me notice something
+a bit unfortunate about the limited-with
+proposal.  Although we don't need a new
+kind of compilation unit, we do need a new
+way of compiling a unit in the non-source-based
+environment.  (I'll call this new way of compiling
+"preregistering" the unit.)  Supporting limited-with
+means that either the programmer preregisters
+all compilation units on the off chance they might
+be mentioned in a limited-with, or the compilation-order-
+determination tool gets smarter and figures out which
+units need to be "preregistered" and which don't.
+
+Having this additional step could have significant
+ripple effects into "make" scripts, regression
+testing scripts, ACATS testing scripts, compilation-order-
+determination tools, etc.  It also means a new
+step to explain to programmers.
+
+None of the above is particularly rocket science, but
+it does add to the implementation and "deployment" cost
+of this proposal.
+
+In general, I think this might emerge as a very
+elegant solution, possibly as elegant as the package
+prefix/abstract approach, but significantly more
+implementation effort than either the "type C.T;"
+or the possibly modified/restricted type stub proposal.
+
+By the way, although it sounds like implementing
+"type C.T;" in Randy's compiler might be a bit
+more work than a restricted type stub, it seems like that is
+small potatoes compared to the heavy lifting involved
+in the limited-with proposal.
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Monday, February  3, 2003  8:53 PM
+
+BY the way, this discussion of what is and is not required of compilers
+reminds me that I think it would be good to have an annex for the standard
+that defined a standard interchange format, right down to the bit-level
+coding and file format. That would for example, partly satisy Dan's
+concern about incomaptible source representation issues.
+
+**************************************************************
+
+From: Gary Dismukes
+Sent: Tuesday, February  4, 2003  1:28 AM
+
+> But it seems like whatever solution to the mutual recursion problem we
+> choose, we really need to solve the problem of proliferation of silly
+> type conversions.  Otherwise, these proposals will be nearly unusable.
+
+I tend to agree.  Certainly with the latest "limited with" proposal there
+are generally going to be multiple access types for the same designated type
+and that's true for most of the other proposals as well.  It seems though
+that the models using child packages may be less prone to that since
+the child package could use an access type declared in the parent
+and reexport using a subtype if needed.
+
+> That is, there ought to be an *implicit* conversion between access types
+> in the "safe" cases.  I know we discussed that before.  Is it part of
+> any of these proposals, or is it a separate AI?  I seem to recall that
+> it might be wrapped up with other access-type issues, like allowing "not
+> null" constraints, and access-to-constant parameters.
+
+Perhaps you're thinking of AIs 230 (generalized access types) and 231
+(access-to-constant parameters and null-excluding subtypes).  AI-230
+would allow more things to be declared using anonymous general access
+types, which would increase the number of contexts where implicit
+conversions can occur, though I'm not sure how much help that will be
+for the mutual-dependence cases where there will be multiple distinct
+access types and pointers of those distinct types floating around.
+I suppose it will help to some degree.  In any case, I think it's
+probably best not to wrap a requirement for easier conversions in with
+the AI-217 proposals, as I think that may tend to muddy the discussion
+(even more more than it already is;).
+
+> > And I do still like that "type C.T;" ;-).
+> > (what a pain I can be...)
+>
+> That's a fine solution, IMHO.  Your earlier e-mail about
+> mutually-recursive types being part of the same abstraction
+> makes me comfortable with the idea of tying the solution to
+> child packages.  (See, it *is* possible to convey sensible information
+> about purely aesthetic concerns.  ;-))
+>
+> But I would choose the "limited with" idea, unless it is considered too
+> hard to implement.
+
+My feeling as well.  Tucker's modified child package proposal definitely
+seems the simplest both in description and implementation effort
+(well, I guess Randy doesn't agree with that...), but like others
+I'm somewhat dissatisfied with requiring a child-based model to
+get mutual recursion.  I was finding my mind being drawn back to
+wishing we could just do things as simply as other languages are
+able to, but had decided that such an approach would be tilted too
+much in favor of source-based compilers.  But now that Pascal's
+bravely put forward that very suggestion, I'm happy to line up behind
+it if it stands up to scrutiny.  I think the critical question is how
+much work that approach will be for non-source-based implementations.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  4:04 AM
+
+> Perhaps you're thinking of AIs 230 (generalized access types) and 231
+> (access-to-constant parameters and null-excluding subtypes).  AI-230
+> would allow more things to be declared using anonymous general access
+> types, which would increase the number of contexts where implicit
+> conversions can occur, though I'm not sure how much help that will be
+> for the mutual-dependence cases where there will be multiple distinct
+> access types and pointers of those distinct types floating around.
+> I suppose it will help to some degree.
+
+AI 230 looked quite promising, but it has been on Tuck's action item list for
+about two years, and he didn't do his homework (but then he'll have some time on
+the plane, so you never know...)
+
+> In any case, I think it's
+> probably best not to wrap a requirement for easier conversions in with
+> the AI-217 proposals, as I think that may tend to muddy the discussion
+> (even more more than it already is;).
+
+Agreed.
+
+**************************************************************
+
+From: Robert A Duff
+Sent: Tuesday, February  4, 2003  4:11 PM
+
+I don't want to muddy the discussion *too* much.  But many (if not all)
+of the cyclic-dependency solutions are going to introduce extra access
+type decls.  I don't want folks to reject proposals for that reason.
+Therefore, we need to at least keep an open mind -- assume that the
+access-type-conversion annoyance can be solved.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:02 AM
+
+> In Pascal's proposal, a parent package P can weakly 'with' its children:
+> "weak with P.C;", if you want a mutually dependent pair of types,
+> one in P and one in P.C.  The spec of P will be elaborated before the
+> spec of P.C, as usual.
+>
+> However, it is pointless for P.C to say "weak with P;", because the
+> child-to-parent dependency is necessarily strong (given that there's no
+> proposal to add syntax saying otherwise -- "weak children?").
+>
+> No problems here.  I'm just making some observations.
+
+In my proposal it would also be possible for unit P to say "limited with P", but
+I think we would want to forbid that, as it seems methodologically dubious.  (If
+you follow the model to its logical conclusions, it would for instance allow
+forward references to packages and types within the spec of P.)
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:21 AM
+
+>  The first is where you have a type declaration that depends on another
+> type:
+>
+> type Color is (Red, Green, Blue);
+> type Properties(C: Color) is...;
+>
+> Does the incomplete type for Properties include the discriminant?
+
+I have no doubt that the incomplete type for Properties doesn't include the
+discriminant.  We discussed that issue when we did "with type" and we concluded
+that any other choice was causing endless trouble.
+
+Discriminants of incomplete types are not too useful anyway, they can only be
+used in building contrained access-to-object types.  And the added complexity
+is not worth it.
+
+> I prefer the choice where only private, record and tagged
+> types are incomplete in the limited view.
+
+But then you would need to do a lot of semantic analysis, and you would have to
+define very precisely what happens during a "superficial" compilation.
+Consider for instance:
+
+    type R is record ... end record;
+    type T is new Integer range R'Alignment .. R'Size;
+
+How can T be properly defined if R is incomplete?  And don't tell me that T
+would be some new kind of "incomplete integer type", because that would add so
+much complexity to the language that I'd rather forget about the entire
+proposal.
+
+As Tuck pointed out in his "willies" message, the only way that this model can
+be made to work is if the first phase can be performed by a brain-dead parser.
+
+**************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, February  4, 2003  11:38 AM
+
+Pascal Leroy wrote:
+
+>I have no doubt that the incomplete type for Properties doesn't include the
+>discriminant.  We discussed that issue when we did "with type" and we concluded
+>that any other choice was causing endless trouble.
+
+About 4 AM, I realized that what is needed is the fact that Properties
+is a type with discriminants, notthing more.  But we already have that
+concept well defined, and it covers incomplete tagged types. Then I went
+back to sleep.  So I propose that (incomplete) tagged types and types
+like Properties have unknown discriminants.  This allows incomplete
+discrete types to be treated like other incomplete types, and incomplete
+array types to also be treated as incomplete with unknown discriminants.
+
+>But then you would need to do a lot of semantic analysis, and you would have to
+>define very precisely what happens during a "superficial" compilation.  Consider
+>for instance:
+>
+>    type R is record ... end record;
+>    type T is new Integer range R'Alignment .. R'Size;
+>
+>How can T be properly defined if R is incomplete?  And don't tell me that T
+>would be some new kind of "incomplete integer type", because that would add so
+>much complexity to the language that I'd rather forget about the entire
+>proposal.
+
+The nightmare that woke me up was not quite this case, but related.
+ (Using T'First, etc., of another discrete type.Hiding the literals is
+not enough.)
+
+As for access types, I still think we need to special case those.  At
+first I was only worried about the proliferation of access types with
+the same target.  But then I realized that the type matching nightmare
+gets worse in cases where some of the potential access types are hidden
+by incompleteness.  The messy case is X: T := F.all.  F can be an
+overloaded function, and I would hate to have the legality checked
+twice, especially if one of the checks depended on elaboration order.
+
+There is another painful case though, and I am not sure what to do about
+it...
+
+limited with B;
+package A is
+   type Foo is record...end record;
+   ...
+end A;
+
+with A;
+package B is
+    type TA is access A.Foo;
+    type Bar is record
+       TAC: TA;
+    end record;
+    ...
+end B;
+
+(You can produce variations on this theme by creating a third package in
+the cycle.) We are not talking pathological here, this is part of the
+core functionality.  Now, what is the status of B.TA inside the spec of
+A?  If it is incomplete we get access type proliferation.  If it is an
+access type, is it an incomplete access type? Inquiring minds want to know.
+
+If you prefer, write the example as:
+
+limited with A.B;
+package A is
+    type TA is access B.T;
+    ...
+end A;
+
+package A.B is
+   type T is tagged record...end record;
+   ...
+end A.B;
+
+I can live with this version working where the first one breaks, but now
+we get back to the issue of representation of the access type.  Whether
+it has to be a fat pointer or not will depend on features of T.  Again,
+I can live with that, we just have to determine which features are
+visible.  (Unknown discriminants for T in this case seems minimal.)
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February  4, 2003  2:20 PM
+
+"Robert I. Eachus" wrote:
+
+> About 4 AM, I realized that what is needed is the fact that Properties
+> is a type with discriminants, notthing more.
+
+Why?
+
+>... But we already have that
+>concept well defined, and it covers incomplete tagged types. Then I went
+>back to sleep.  So I propose that (incomplete) tagged types and types
+>like Properties have unknown discriminants.  This allows incomplete
+>discrete types to be treated like other incomplete types, and incomplete
+>array types to also be treated as incomplete with unknown discriminants.
+
+Why can't we treat these all as plain old incomplete types?
+You haven't explained that.
+
+
+>>But then you would need to do a lot of semantic analysis, and you would have to
+>>define very precisely what happens during a "superficial" compilation.  Consider
+>>for instance:
+>>
+>>    type R is record ... end record;
+>>    type T is new Integer range R'Alignment .. R'Size;
+>>
+>>How can T be properly defined if R is incomplete?  And don't tell me that T
+>>would be some new kind of "incomplete integer type", because that would add so
+>>much complexity to the language that I'd rather forget about the entire
+>>proposal.
+>>
+>The nightmare that woke me up was not quite this case, but related.
+> (Using T'First, etc., of another discrete type.Hiding the literals is
+>not enough.)
+
+I am totally lost.  These types are incomplete.  You can't do anything
+with them.
+
+> As for access types, I still think we need to special case those.  At
+> first I was only worried about the proliferation of access types with
+> the same target.  But then I realized that the type matching nightmare
+> gets worse in cases where some of the potential access types are hidden
+> by incompleteness.  The messy case is X: T := F.all.  F can be an
+> overloaded function, and I would hate to have the legality checked
+> twice, especially if one of the checks depended on elaboration order.
+
+I must be missing something fundamental here.  All of these types are
+just plain old incomplete types.  Yes, I agree we ought to special
+case tagged and allow a bit more, but that seems irrelevant to
+what you are talking about.  What is messy about the messy case?
+
+>...
+>(You can produce variations on this theme by creating a third package in
+>the cycle.) We are not talking pathological here, this is part of the
+>core functionality.  Now, what is the status of B.TA inside the spec of
+>A?  If it is incomplete we get access type proliferation.  If it is an
+>access type, is it an incomplete access type? Inquiring minds want to know.
+
+It is incomplete and we get access type proliferation.
+
+I don't see that "limited with" can solve the access type proliferation
+problem, and trying to make it do so is doomed, in my mind.
+
+...
+>I can live with this version working where the first one breaks, but now
+>we get back to the issue of representation of the access type.  Whether
+>it has to be a fat pointer or not will depend on features of T.  Again,
+>I can live with that, we just have to determine which features are
+>visible.  (Unknown discriminants for T in this case seems minimal.)
+
+I am presuming that all non-tagged types are incomplete, period.  No new
+notion of "incomplete access types" is being added.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:00 PM
+
+> > So I propose that (incomplete) tagged types and types
+> > like Properties have unknown discriminants.  This allows incomplete
+> > discrete types to be treated like other incomplete types, and incomplete
+> > array types to also be treated as incomplete with unknown discriminants.
+>
+> Why can't we treat these all as plain old incomplete types?
+> You haven't explained that.
+
+I am as puzzled as Tuck.  It is my understanding that unknown discriminants
+for incomplete types are pretty much equivalent to no discriminants.  So
+it's fine with me to insist that these types have unknown discriminants, but
+it doesn't make the slightest difference.  (Remember, we are talking
+_incomplete_ types here, so you cannot do much with them anyway.)
+
+> I am presuming that all non-tagged types are incomplete, period.  No new
+> notion of "incomplete access types" is being added.
+
+Agreed.  This seems like the only way to avoid madness.  Granted, this
+proposal doesn't solve the problem of proliferation of access types, but
+that problem shows up in contexts that are unrelated to circular type
+dependencies, so I think that it should be addressed by a different
+mechanism.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February  4, 2003  2:53 PM
+
+Tucker said, replying to Robert Eachus:
+> > If it is incomplete we get access type proliferation.  If it is an
+> > access type, is it an incomplete access type? Inquiring
+> > minds want to know.
+>
+> It is incomplete and we get access type proliferation.
+>
+> I don't see that "limited with" can solve the access type proliferation
+> problem, and trying to make it do so is doomed, in my mind.
+
+At which point, I lose interest in the proposal.
+
+All of type stubs, restricted type stubs, and Tuck's type C.T idea do solve
+the access type proliferation problem. Admittedly the structure of the
+declarations is unnatural. But the only real alternative is to adopt
+something like AI-230. That bulks up the proposal a ton.
+
+So, limited with:
+   -- Is much harder to implement in library based compilers. It's probably
+harder to implement than type stubs/type C.T in source-based compilers as
+well (certainly no easier). Affects compilation tools in all environments;
+   -- Doesn't solve the access type proliferation problem.
+
+The only advantage seems to be:
+   -- A more natural expression of package structure.
+
+But that's dubious, since you need to resort to unnatural package structures
+in order to share access types. So you're pretty much left with "much harder
+to implement".
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:09 PM
+
+> > I don't see that "limited with" can solve the access type proliferation
+> > problem, and trying to make it do so is doomed, in my mind.
+>
+> At which point, I lose interest in the proposal.
+
+Access type proliferation in and of itself is not a problem.  What is a
+problem is access type conversions.  That problem shows up in all sorts of
+contexts, notably in OOP where you have access types (class-wide or
+specific) designating some type in a hierarchy, and all conversions must be
+explicit, even those that cannot possibly fail.  That is a big pain.
+
+This has nothing to do with circular type dependences.  Even if we select a
+solution to the problem of circular type dependences that doesn't cause
+proliferation of access types, the problem of access type conversions will
+remain.
+
+In C, if you have a type t you automatically get a pointer type t*.  In Ada,
+I often wish we had a similar capability, where I wouldn't have to declare
+all these silly access types and convert between them explicitly.
+
+**************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, February  4, 2003  5:20 PM
+
+Tucker Taft wrote:
+
+>It is incomplete and we get access type proliferation.
+>
+>I don't see that "limited with" can solve the access type proliferation
+>problem, and trying to make it do so is doomed, in my mind.
+
+And in my mind the proposal is doomed (or not the best one on the table)
+if it doesn't address the access type proliferation problem.
+
+>I am presuming that all non-tagged types are incomplete, period.  No new
+>notion of "incomplete access types" is being added.
+
+Hmm.  I must not be making myself clear.  My idea is not to add
+"incomplete access types," but to try to make the limited with idea work
+with access types to these new special incomplete types.  The refractory
+issue is when you have access types that carry descriptor information
+and when you don't.  Where that data is stored is irrelevant.  Even if
+you store the descriptor for an unconstrained array type with the data
+and pointers to both unconstrained and constrained arrays are the same
+size, some conversions and assignments are impossible or require
+recopying the data:
+
+package P is
+     type Str is new String;
+     subtype Str4 is Str(1..4);
+     type PT1 is access Str;
+     type PT2 is access Str4;
+end P;
+
+or if you prefer:
+
+limited with P;
+package Q is
+  type PT3 is access P.Str;
+  type PT4 is access P.Str4;
+end Q;
+
+Now I need to compile some code--perhaps the body of Q--that needs to do
+those damned explicit type conversions, or even just some simple
+assignments.  As a programmer I have a problem, but without more
+information about the types in P than Tuck seems willing to allow, the
+compiler is SOL.  It doesn't know how to create objects of type PT3
+and/or PT4, and even has trouble with legality issues:
+...
+PO3: PT3;
+PO4: PT4;
+...
+PO3.all := PO4.all; -- legal?
+
+Right now the voting seems to be that either the limited with idea is
+doomed because it is too much work, or it is doomed because it can't
+deal with the issue of access type proliferation.  I'll let sleeping
+dogs lie.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February  4, 2003  5:58 PM
+
+"Robert I. Eachus" wrote:
+>
+> Tucker Taft wrote:
+>
+> >It is incomplete and we get access type proliferation.
+> >
+> >I don't see that "limited with" can solve the access type proliferation
+> >problem, and trying to make it do so is doomed, in my mind.
+> >
+> And in my mind the proposal is doomed (or not the best one on the table)
+> if it doesn't address the access type proliferation problem.
+
+Well, I think trying to make it address this problem very tricky,
+since it means looking at the designated subtype indication,
+and that will get you back to worrying about use visibility, etc.
+
+> >I am presuming that all non-tagged types are incomplete, period.  No new
+> >notion of "incomplete access types" is being added.
+> >
+> Hmm.  I must not be making myself clear.  My idea is not to add
+> "incomplete access types," but to try to make the limited with idea work
+> with access types to these new special incomplete types.  The refractory
+> issue is when you have access types that carry descriptor information
+> and when you don't.  Where that data is stored is irrelevant.  Even if
+> you store the descriptor for an unconstrained array type with the data
+> and pointers to both unconstrained and constrained arrays are the same
+> size, some conversions and assignments are impossible or require
+> recopying the data:
+
+I am getting an inkling of your concern.  At least one of the
+problems you seem to be worrying about is an implementation
+issue (as opposed to a semantics issue), and is one that bedevils
+the "unrestricted" type stub proposal, and the "with type"
+proposal.  Namely that when choosing a representation for access types
+to the full type, the compiler may not be aware that there are
+access types to the incomplete type.  I don't think this is quite
+as serious as the problem with the "with type" proposal, since
+the compiler is doing some serious peeking at the full type
+when it creates the incomplete type, so *if* it has multiple
+access type representations, it can mark the incomplete type
+with enough extra information so that it will choose an appropriate
+representation for any access type that is declared later which
+"sees" only the incomplete type.
+
+Unfortunately, derived types create a bit of a problem, since they
+don't reveal syntactically what sort of type they are (e.g.,
+whether their first subtype is an unconstrained array subtype and
+hence pointers to it should be default be "fat" pointers).
+This would mean that the "peeker" would have to make a "guess"
+about whether the incomplete type is an unconstrained array.
+Probably it would assume all derived types are not
+unconstrained arrays.  In any case, whatever guess it makes,
+it would want to record that in the limited view of the package.
+When the full view is compiled, as part of the "compatibility"
+check it would also have to check that the "guess" was correct.
+If the guess was wrong, and the type is in fact an unconstrained array,
+say, then it would have to record that fact on the incomplete
+type, and bump the timestamp (or equivalent) of the limited view
+of the package.  Ultimately the units that depend on this limited
+view would get recompiled.
+
+For a source-based compiler, there isn't really any place to
+permanently record the "correct" answer, so it would probably
+end up being a link-time check, and if there were an incompatibility,
+the offending units would be recompiled with a switch directing
+them to treat the problematic incomplete type as an unconstrained array,
+even though it wasn't obvious.
+
+
+>
+> package P is
+>      type Str is new String;
+>      subtype Str4 is Str(1..4);
+>      type PT1 is access Str;
+>      type PT2 is access Str4;
+> end P;
+>
+> or if you prefer:
+>
+> limited with P;
+> package Q is
+>   type PT3 is access P.Str;
+>   type PT4 is access P.Str4;
+
+This wouldn't be legal, since Str4 is defined by a subtype, not
+a type declaration.
+
+> end Q;
+>
+> Now I need to compile some code--perhaps the body of Q--that needs to do
+> those damned explicit type conversions, or even just some simple
+> assignments.  As a programmer I have a problem, but without more
+> information about the types in P than Tuck seems willing to allow, the
+> compiler is SOL.  It doesn't know how to create objects of type PT3
+> and/or PT4, and even has trouble with legality issues:
+
+I don't see how legality issues enter into the problem of access
+type representation.  You can't do much of anything with incomplete types.
+And you can't dereference access-to-incomplete, unless perhaps
+there is a complete type "nearby".
+
+> ...
+> PO3: PT3;
+> PO4: PT4;
+> ...
+> PO3.all := PO4.all; -- legal?
+>
+> Right now the voting seems to be that either the limited with idea is
+> doomed because it is too much work, or it is doomed because it can't
+> deal with the issue of access type proliferation.  I'll let sleeping
+> dogs lie.
+
+I don't think it has been abandoned, so it is still important
+to try to identify (real ;-) problems associated with the
+proposal.
+
+**************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, February  4, 2003  6:34 PM
+
+Tucker Taft wrote:
+
+>Well, I think trying to make it address this problem very tricky,
+>since it means looking at the designated subtype indication,
+>and that will get you back to worrying about use visibility, etc.
+
+Yep.
+
+...
+>For a source-based compiler, there isn't really any place to
+>permanently record the "correct" answer, so it would probably
+>end up being a link-time check, and if there were an incompatibility,
+>the offending units would be recompiled with a switch directing
+>them to treat the problematic incomplete type as an unconstrained array,
+>even though it wasn't obvious.
+
+Yep, it is a problem in any solution to the mutual dependence problem.
+ The issue here is deciding what aggrevations to add--to the user, the
+implementor, or both.  We could make fairly draconian rules that stated
+that any unit that actually uses a subtype, access type to, or type
+derived from one of these magic incomplete types  must depend on the
+limited withed unit, and thus see the full type.  I think so far this
+has been an implicit assumption, but the devil is in the details.
+
+To take your discussion above a bit further, what happens when you
+modify the limited withed unit in a way that changes the necessary
+representation of an access type declared elsewhere?  It begins to look
+like a very real dependence somehow magically wished away.  You end up
+having to recompile some units due to changes in units they don't depend
+on....
+
+>I don't think it has been abandoned, so it is still important
+>to try to identify (real ;-) problems associated with the
+>proposal.
+>
+Consider the (dead) horse to have been additionally flogged.
+
+**************************************************************
+
+From: Robert A Duff
+Sent: Tuesday, February  4, 2003  7:06 PM
+
+Note that we already have a case where you can create
+access-to-incomplete without knowing what the complete type
+looks like.  Namely, an incomplete type declared in a package
+spec, and completed in the body.
+
+**************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, February  4, 2003  10:34 PM
+
+What did we used to call that?  Ah, yes, I remember the Tucker Taft
+amendment. ;-)  The only good thing about it was that the incomplete
+type had to be private, so it couldn't be seen outside the package.
+
+If you weren't following LMC/ARG actions then look up (Ada-83) AI-7.
+ For one meeting, John Goodenough put the AI's for consideration in two
+books--AI-2 and AI-7, plus related AI's, and everything else.  (The
+final version of AI-00007/19-BI-WJ--yes that is version 19--is actually
+a consolidation of about a dozen separate AI's)
+
+As I recall, AI-7 underwent combinatorial explosion, we discovered lots
+of nits and crannies, and finally came up with a smoking gun case that
+did not require the TTA to fire off.  But if you think my concern about
+access to incomplete types with discriminants  is overdone, you really
+should go back and look at all those AI's.  As I recall, the final
+version of AI-7 allowed the legality check on discriminant constraints
+of access to incomplete objects to be done in one of three
+places--because there were cases when each of the three wouldn't work,
+and in some cases more than one.
+
+Any "solution" to the interlocking types problem that re-opens that can
+of worms should be shot then burned and the ashes stirred and buried
+under a crossroads at midnight.  I think net that AI-7 and its relatives
+took the equivalent of several three-day meetings to resolve. (This was
+"fixed" in Ada 95 by deferring all compatibility checks until object
+creation.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:55 AM
+
+> At the moment, I think it's too hard to implement (given that type stubs are
+> expected to take 4 hours of work; this would be more like 4 weeks). But that
+> may be irrelevant. More important is that I don't see any way, within the
+> current design of Janus/Ada, to implement something like this.
+
+Not sure how you came up with the 4 hours estimate, but I'm sure it would take
+me more than that to do a detailed design.  At this point I'd say that the
+implementation effort for any of these proposals would be in the range 4 weeks
+.. 4 months, and I can't be more specific without doing a detailed analysis.
+But anyway, I don't think that numbers are very interesting at this point.  It's
+really the essence of the implementation difficulties that need to be looked at.
+
+As far as I can tell, you and I have the same set of problems, because we are
+both library-based.  I realize that the devil is in the details, and that the
+magnitude of changes can vary substantially from one implementation to another,
+but I don't buy that the "limited with" proposal would force you to go to a
+source-based model.  (For Rational, going to a source-based model is a no-no;
+we'd rather get out of the Ada business; so hopefully there has to be an
+implementation technique where we stick to our current library model.)
+
+> The problem is with the obsoleteness check. Janus/Ada uses a serial number
+> created from the time stamp of the symbol table file created for a library
+> unit for checking. Also, the Janus/Ada compiler knows nothing about source
+> files other than the one it is compiling at the moment. (Other tools are a
+> bit smarter, but the compiler does not use that information itself.) It only
+> knows about symbol table files.
+
+Fine.  If I substitute "Diana tree" for "symbol table", that's essentially true
+of Apex too.  (Ignoring all the incremental compilation crap.)
+
+> One presumes that you'd have a new kind of symbol table file that held a
+> 'lightly' compiled package spec for limited withs. And you'd use the time
+> stamp of that file to create the serial number for obsoleteness checking.
+> Clearly, when you 'really' compiled the spec, the new kind of package spec
+> would have to be updated (otherwise, it wouldn't necessarily match the
+> source file, because the source file could have been edited).
+
+And we would indeed have the same problem.  We would first created a "parsed"
+Diana tree (during "superficial" compilation) and then we would rewrite it to
+make it "analyzed" (during "full" compilation).  Surely that would change the
+timestamp.
+
+> But that would
+> necessarily change the serial number, and then the links would fail. And
+> there would be no way to avoid the problem.
+>
+> Given that there is no reliable way to determine if a file has been changed
+
+The way that I plan to do this is to store in the "parsed" Diana tree (what you
+call the "light symbol table") a hash code.  This hash code could be based on
+the sequence of tokens in the source, or it could be more clever and be based
+only on the names of types and packages (the information that is available after
+"superficial" compilation).  Whenever clients currently use a timestamp to check
+for obsolescence, they would use the combination <timestamp, hash>.  If the
+timestamps match, everything is fine.  Otherwise, the Diana trees need to be
+opened, and the hashes need to be compared.  I realize that this will result in
+some extra open system calls, but Ada's separate compilation already requires a
+zillion system calls, so I won't lose any sleep on that.
+
+Of course, a hash code is not exactly 100% safe, as there could be collisions.
+But if you design it well enough, you won't see a collision in your lifetime.
+(We use 96-bit hash codes all over the place for incremental compilation, and we
+have never run into a collision in all these years.)
+
+> This also has a giantic impact on build tools. They'd have to be able to
+> process this new clause and come up with an appropriate order in the face of
+> cycles. Of course, tools just punt if that happens now.
+
+But the trick is that there are no prerequisites for "superficial" compilation.
+So one approach is to blindly run "superficial" compilation over all the units,
+in any order you like (e.g. the order of i-nodes in the filesystem if you like).
+And then run "full" compilation in an order compatible with normal with clauses
+and other semantic dependencies, just like you do now (and ignoring "limited
+with" clauses).  No need to process the new clause, no need to change the
+algorithm that determines the compilation order.
+
+Of course you might want to be more clever and avoid the "superficial" phase if
+it's not needed, but that's an optimization, not something you would have to do
+for correctness.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  4:00 AM
+
+> Supporting limited-with
+> means that either the programmer preregisters
+> all compilation units on the off chance they might
+> be mentioned in a limited-with, or the compilation-order-
+> determination tool gets smarter and figures out which
+> units need to be "preregistered" and which don't.
+
+As I mentioned in my previous response to Randy, it would be just fine if the
+compilation-order-determination tool were to systematically preregister each and
+every unit, and then run the normal ordering algorithm, ignoring "limited with"
+clauses.  I would think that compiler writers would prefer to go that way,
+rather than breaking each and every compilation script in the universe.  So I am
+arguing that the new step should be essentially invisible to programmers.
+
+In an implementation where the preregistration step would be costly, then yes,
+the ordering algorithm might have to be modified to avoid preregistration when
+possible.
+
+**************************************************************
+
+From: Erhard Ploedereder
+Sent: Tuesday, February  4, 2003  7:38 AM
+
+I like "limited with". It is the closest we got to what the user expects.
+I would like to see a writeup.
+
+(I have had bellyaches with Tuck's proposal of tying the cyclic dependency
+ to child packages. I waited for the aches to go away. They did not.)
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February  4, 2003  3:00 PM
+
+> > At the moment, I think it's too hard to implement (given that type stubs are
+> > expected to take 4 hours of work; this would be more like 4 weeks). But that
+> > may be irrelevant. More important is that I don't see any way, within the
+> > current design of Janus/Ada, to implement something like this.
+>
+> Not sure how you came up with the 4 hours estimate, but I'm sure it would take
+> me more than that to do a detailed design.
+
+I did a detailed design (in my head) when I was unable to sleep Saturday
+night.
+
+> At this point I'd say that the implementation effort for any of these proposals
+> would be in the range 4 weeks .. 4 months, and I can't be more specific without
+> doing a detailed analysis. But anyway, I don't think that numbers are very
+> interesting at this point.  It's really the essence of the implementation
+> difficulties that need to be looked at.
+
+The reason I was thinking about it was that the restricted type stubs model
+pretty much matches how Janus/Ada works internally anyway. So the main cost
+is "connecting" the stub to the completion. (And many stubs works, because
+it's a one-way pointer. But I wouldn't expect that to be true on other
+implementations.) Since incomplete and private types use the same code in
+most circumstances, the visibility implications of "availability" should be
+free. (That is the biggest assumption, of course, because there are no such
+rules in Ada 95.) So all of the work is doing the connection, and a brute
+force version (walk all of the symbol table looking for stubs, then when a
+stub is found, walk the whole symbol table looking for a connection) would
+only need to be called in one place. Most of the work is figuring out where
+to call that routine. A better version would save the stubs in a list as
+they are loaded, so we wouldn't have to search for them. That version would
+have no distributed cost and not a lot of cost even when stubs are used, so
+I doubt its possible to do better.
+
+Tucker's C.T adds a lot of messing around with ghost packages, but otherwise
+is identical (we don't have to look quite so far for a completion, but the
+process is the same). Which is why I'm certain its more work.
+
+The current stub stubs requires two stubs of the same completion to match,
+even when the completion isn't available. That's more work, but I don't
+think it's a very significant amount (it's just another weird special case
+in the type matcher, just like anonymous access types and T'Class).
+
+In all of these cases, I wouldn't be surprised to find glitches, but that
+would require a pretty complete test suite. Building that would take longer
+than doing the implementation (that is often true).
+
+Limited with would require a new kind of symbol file, or something (Pascal
+suggests a hash). It also would require going in an adding a bunch of stuff
+to the make tool. No one understands how that thing really works, so that
+alone is a daunting project. And the failure to provide any sort of solution
+to the access type problem makes it feel like "with type" all over again
+(which isn't surprising, because it *IS* essentially "with type", just as
+"type C.T" is just a different syntax for type stubs).
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:17 PM
+
+> Since incomplete and private types use the same code in
+> most circumstances, the visibility implications of "availability" should be
+> free.
+
+Aren't you concerned about types having three views (incomplete, partial,
+full) in the case of an incomplete type completed by a private type?  That
+gives me the willies, to borrow Tuck's words, because it's currently very
+complicated in our compiler to decide what properties of a type are visible
+at a given place (because of the separation between partial and full view,
+because of characteristics that become visible "later within the immediate
+scope", etc.).  Adding a third view is not going to make this easier.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February  4, 2003  3:43 PM
+
+No, because we have separate type records for each view, and they have their
+own visibility. For type matching purposes, the only question is whether you
+can or cannot walk the pointer to the 'next' view, as we always match (and
+use for other purposes) the "fullest" view available. That depends on
+visibility, etc. (We have a separate set of routines that always goes to the
+completion, which the intermediate code generation uses. To heck with
+visibility at that point.) Since this stuff is recursive (well, actually it
+uses a loop), you'd first try to go from the incomplete block to the private
+block (depending on the visibility of the private), and then, once you had
+the private, you'd do the checks that we currently have. So I don't see a
+problem with three parts or ten parts for that matter.
+
+But I realize that if you somehow managed to implement types with a single
+record for both views (we tried that and concluded it was impossible. But
+perhaps we weren't clever enough. Or perhaps its impossible because of
+shared generics.), it might be much worse.
+
+But I think that any proposal has to allow stubs (or whatever) of private
+types. So you're going to have the three view issues, and if that is a
+problem, any solution to this problem will be a nightmare to implement. In
+which case you ought to stay out of the implementation difficulty debate
+altogether. :-) :-)
+
+**************************************************************
+
+From: Gary Dismukes
+Sent: Tuesday, February  4, 2003  3:20 PM
+
+Pascal wrote:
+> In my proposal it would also be possible for unit P to say "limited with P", but
+> I think we would want to forbid that, as it seems methodologically dubious.  (If
+> you follow the model to its logical conclusions, it would for instance allow
+> forward references to packages and types within the spec of P.)
+
+One question is, what does it mean when you say "limited with P.C.D".
+Is it equivalent to having limited with for P, P.C, and P.C.D, in
+analogy with normal with clauses?  That was my first thought, and
+it seems natural to make it behave the same, but perhaps it's more
+reasonable to say it only applies to the final named unit.  That
+would avoid the issue of self-circular references when a parent
+withs its child and we would also want the rules to disallow
+a direct limited with of yourself.
+
+Another small issue is whether use clauses are allowed for packages
+named in these with clauses.  I imagine that the implementation is
+effectively going to create a package entity containing an incomplete
+type representative for each type in the real package's visible part
+(along with representatives for any nested packages presumably)
+and since this will look essentially the same as other packages
+in the symbol table environment I don't see any technical problem
+with permitting a use clause for these packages.  Perhaps there are
+methodological reasons for not allowing it, though I can't think
+of any.  Changing a limited with to a normal with could introduce
+new illegalities due to name clashes, but that's no worse than
+adding a new with and use clause for some package.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, February  4, 2003  3:30 PM
+
+> One question is, what does it mean when you say "limited with P.C.D".
+> Is it equivalent to having limited with for P, P.C, and P.C.D, in
+> analogy with normal with clauses?  That was my first thought, and
+> it seems natural to make it behave the same, but perhaps it's more
+> reasonable to say it only applies to the final named unit.  That
+> would avoid the issue of self-circular references when a parent
+> withs its child and we would also want the rules to disallow
+> a direct limited with of yourself.
+
+From a pedagogical standpoint it would seem simpler to say that "limited
+with" works like "with", i.e. that "limited with P.C.D" is equivalent to
+"with P, P.C, P.C.D".  Any other option is going to unnecessary confuse
+users.
+
+So maybe the right answer is that if a package has a "limited with" of
+itself it has no effect (but is not illegal).
+
+> Another small issue is whether use clauses are allowed for packages
+> named in these with clauses.  I imagine that the implementation is
+> effectively going to create a package entity containing an incomplete
+> type representative for each type in the real package's visible part
+> (along with representatives for any nested packages presumably)
+> and since this will look essentially the same as other packages
+> in the symbol table environment I don't see any technical problem
+> with permitting a use clause for these packages.
+
+Yes, I was thinking that use clauses and package renamings would be OK in
+that context, although if they lead to problems we could disallow them.  But
+I can't think of any problem at this point.
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, February  4, 2003  10:19 PM
+
+> In C, if you have a type t you automatically get a pointer type t*.  In Ada,
+> I often wish we had a similar capability, where I wouldn't have to declare
+> all these silly access types and convert between them explicitly.
+
+For some reason, I never really understood it, this proposal, which I was strongly
+in favor of, never got significant support (I had suggested early on calling it
+type'access).
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February  4, 2003  3:27 PM
+
+In discussing this further with Bob Duff, and mulling it over
+more in my mind, I see the following restrictions would probably
+be needed on the "limited with" capability.  I am using the term
+"limited view" of a package to be what you get when you mention
+a package in a limited-with-clause.  I am presuming that a limited
+view of a package contains only nested packages and types, and all
+the types are [tagged] incomple.
+
+A "limited with" *cannot* make the following declarations visible:
+  1) Package instantiation
+       Because the generic being instantiated needs to be visible
+       if we are to determine what types it contains, and identifying
+       the generic may require resolving a name that is only use-visible,
+       or that is from some other compilation unit
+
+  2) Package renaming
+       Because the package being renamed needs to be visible
+       if we are to determine what types it contains, and identifying
+       the renamed package may require resolving a name that is only use-visible,
+       or that is from some other compilation unit
+
+A "limited view" of a package *cannot* be mentioned in:
+  3) A "use" clause
+       Because we can get a funky kind of Beaujolais effect if we have
+       a "use" clause for two different packages, and due to
+       changing a "normal" with clauses inherited from some ancestor unit
+       the meaning of an identifier switches from one thing to another; e.g.:
+
+        package A is
+             X : Integer := 7;
+        end A;
+
+        package B is
+             X : Integer := 203;
+        end B;
+
+        with A;  -- change this to "with B;" and see what happens
+        package P is end;
+
+        limited with A, B;
+        use A;
+        use B;  -- Probably shouldn't be allowed if only have limited view
+        package P.C is
+            Y : Integer := X;  -- which X is this?
+        end P.C;
+
+       This is presuming that if we were to allow a "use" clause for a limited
+       view of a package, it would make only the types and subpackages directly visible.
+       If the "use" clause made everything in the package visible part
+       visible, but only the types were actually "usable" that could work,
+       but having visible but unusable declarations of *all* kinds,
+       rather than just types and packages, could significantly increase the effort
+       of building up a limited view.
+
+  4) A package renaming declaration
+      This restriction is probably not as critical as the others.
+      The problem comes when someone from outside the unit containing
+      the limited with references this package renaming.  What does it see?
+      If it has a "regular" with for the target of the limited-with, does
+      it see the "full" view of the package via the renaming, or only the
+      limited view of it.
+
+Possible restriction (4) brings up the issue of the opposite situation, where
+a given unit has a limited view on a package, but also has visibility
+on a renaming of a full view of the package.  There seem to be various
+possibilities:
+
+   a) The renaming also provides only a limited view when referenced from the given unit.
+   b) The given unit has a full view of the package, through either the
+      renaming or the name introduced by the limited-with clause
+   c) The given unit has a limited view via the name introduced by the limited-with
+      clause, and a full view via the renaming, and they are essentially
+      completely unrelated packages.
+   d) (c), except the packages are recognized as different views of the same
+      package, and the incomplete types in the limited view are recognized
+      as being completed in the renaming, and so are treated as non-limited
+      types for all intents and purposes.
+
+(a) is probably the most consistent with the way package renamings work now,
+in that what children you see via a renaming of a library unit package is determined
+by the "with" clauses in the unit referencing the renaming, rather than by the
+with-clauses in the unit containing the renaming.
+
+(b) and (d) are both similar to the choice I suggested for "type C.T;" where
+if the completing type declaration is visible (including presumably via
+a renaming), then the incomplete type declaration is hidden from
+all visibility.  In the "type C.T;" proposal, this presumably implies
+that it is as though the "type C.T;" declaration were not there at all,
+so if a renaming "package R renames C;" is visible, but "C" itself is
+not visible (because C was not directly "withed"), then you *cannot*
+refer to the type at all via "C.T."   You can refer to it via "R.T"
+and then of course it is a full type.
+
+There are other possible ways of handling this for "type C.T;"
+but this approach required the smallest change to 18.3(19) and at
+least makes some kind of sense.
+
+For all proposals, the issue of visible renamings of the enclosing package
+when the package itself is not visible is thorny.  A related question is when the
+completing type is *not* visible (including not via a renaming), but a declaration of a subtype
+*is* visible, or an object of the type is visible.  The questions are always:
+
+   i) Is the type named via the "limited view" name complete or incomplete?
+
+   ii) If incomplete, does it nonetheless "match" the complete type in certain
+       contexts?
+
+To put it more concretely:
+
+  package P1 is
+    type A is access <incomplete view of type P2.T>;
+      -- incomplete view is visible via a limited with, type stub, type C.T, or whatever
+    Y, Z : A;
+  end;
+
+  package P2 is
+      type T is <full type definition>;
+  end P2;
+
+  with P2;
+  package P3 is
+    X : <subtype of complete view of P2.T>;
+  end P3;
+
+  with P1, P3;  -- No "with" of P2, no visibility on P2.T
+  procedure P4 is begin
+      ...
+    P3.X := P1.Y.all;  -- when is this legal?   (*)
+    P1.Y.all := P3.X;  -- same question         (**)
+    if P1.Y.all = P1.Z.all then  -- same question (***)
+      ...
+
+Hopefully the answers to (*) and (**) are the same, though
+the asymmetric Name Resolution wording of 5.2(4) on assignment
+statements seems like (*) and (**) might be treated differently
+unless we are careful.
+
+Note that last time we worked on the "availability" rules for type stubs,
+we required that either we be in the scope of a with clause for
+the enclosing package (or a renaming thereof, I presume), or we be in a context
+where we have the complete type "nearby" (I forget the wording at this
+point).  This would say that having a visible (but not "with"ed)
+renaming of the enclosing package, or having a visible subtype,
+wouldn't help.  For the above cases, this would mean that probably
+(*) and (**) would be legal, but (***) would not be legal.
+
+Have a nice day... ;-)
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February  4, 2003  3:48 PM
+
+Pascal Leroy wrote:
+> Randy wrote:
+> > One presumes that you'd have a new kind of symbol table file that held a
+> > 'lightly' compiled package spec for limited withs. And you'd use the time
+> > stamp of that file to create the serial number for obsoleteness checking.
+> > Clearly, when you 'really' compiled the spec, the new kind of package spec
+> > would have to be updated (otherwise, it wouldn't necessarily match the
+> > source file, because the source file could have been edited).
+>
+> And we would indeed have the same problem.  We would first created a "parsed"
+> Diana tree (during "superficial" compilation) and then we would rewrite it to
+> make it "analyzed" (during "full" compilation).  Surely that would change the
+> timestamp...
+
+After talking with Bob Duff about this a bit, I don't think this
+really works.  I think you need to keep around indefinitely both a "full view"
+of the package and a "limited view" of the package.  Even after you
+do a "full" compile, some units can still do "limited with" and should only
+see the limited view.  What I would recommend is you treat them as
+pretty much distinct units.  When you fully compile, if there is a limited
+view already present, you could check that it is compatible with the full view
+(i.e. has the same names in the package/type tree, and the same types are
+tagged).
+
+I think if they are not compatible, then and only then does it seem worth
+obsoleting the limited view and any units compiled against it.  There seems no
+point in hashing the incomplete view, since it is easy enough to check
+compatibility.  Hashing would only be an optimization if this compatibility
+check turned out to be really expensive.
+
+If a unit requests a limited view, and the only non-obsolete thing you have around
+is the full view, I would at that point create the limited view from the full view.
+I would bump the time stamp on the limited view only when it is created or updated,
+and units compiled against the limited view only worry about that time stamp.
+The time stamp of the full view is irrelevant to them.
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February  4, 2003  4:13 PM
+
+"Easy enough to check compatibility"? You've got to be kidding. The only
+thing that we know how to do with a symbol file is load them into a symbol
+table. But you can't do that to "check compatibility", because you've got to
+load the full view into the same place (can't have two packages with the
+same library-level name).
+
+Pascal's hash idea (instead of a time stamp) makes much more sense. You'd
+create the limited symbol file for every compilation (full and limited) that
+you did, but the hash would only change if it actually is different.
+
+Keep in mind that no one actually "obsoletes" anything. How we do
+obsoleteness checking is simply to compare the time stamp serial numbers of
+every unit withed transitively for every unit withed. They better all match.
+Any mismatch is reported as an error, and the compilation aborted. And we of
+course repeat the check when linking. We use the order only to provide
+better error messages, and units are NEVER removed from the program library
+(unless the programmer does so manually).
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February  4, 2003  5:05 PM
+
+> "Easy enough to check compatibility"? You've got to be kidding. The only
+> thing that we know how to do with a symbol file is load them into a symbol
+> table. But you can't do that to "check compatibility", because you've got to
+> load the full view into the same place (can't have two packages with the
+> same library-level name).
+
+This is my whole point.  You *do* need to have both views available
+at once, since one unit might have a "limited with" of package P,
+while some unit that it depends on indirectly has a full "with" of P.
+To avoid ripple effects, we want the one with the limited-with
+to only see the limited view.
+
+You mentioned in another note that you have separate symbol table
+entries for various different forms of a type.  I think you will
+need separate symbol table entries for the limited view and
+the full view.  In other words, for a library package P, you really have two units,
+one whose library-level name is "P-full" and one whose name is "P-limited".
+
+> Keep in mind that no one actually "obsoletes" anything. How we do
+> obsoleteness checking is simply to compare the time stamp serial numbers of
+> every unit withed transitively for every unit withed. They better all match.
+
+Yes, I understand that approach. I probably should have simply
+talked in terms of bumping time stamps.  I think the same
+point can be made in those terms.  We have a similar model,
+albeit only in the program library we build up in memory.
+[Since we allow the compiler to run for a "long" time and
+to process different versions of the same file during a single
+execution, we have all the obsoleteness checking mechanism
+in there as well.]
+
+**************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February  4, 2003  5:34 PM
+
+> This is my whole point.  You *do* need to have both views available
+> at once, since one unit might have a "limited with" of package P,
+> while some unit that it depends on indirectly has a full "with" of P.
+> To avoid ripple effects, we want the one with the limited-with
+> to only see the limited view.
+
+I don't see that. Each compilation has its own symbol table, and I don't see
+any reason why the mere fact of withing something that saw a limited view of
+some package was anything to do with a package that sees the full view.
+
+> You mentioned in another note that you have separate symbol table
+> entries for various different forms of a type.
+
+No, "types" aren't in the symbol table at all. They have their own separate
+table. Type names are in the symbol table, of course, as are component
+names. But a type name has nothing to do with a type -- they're completely
+separate concepts (as they are in Ada).
+
+> I think you will
+> need separate symbol table entries for the limited view and
+> the full view.  In other words, for a library package P, you really have
+> two units, one whose library-level name is "P-full" and one whose name
+> is "P-limited".
+
+If that's true, we're getting into horrific complexity territory. A
+fundamental basis of the symbol table is that most entities have only one
+name and cannot be overloaded. You're asking that all of the lookup code be
+changed to be able to handle packages with two views. Along with all of the
+declaration code (so it can write into the correct view). Moreover, that
+would be true in every compiler (source based or library based).
+
+If the proposal requires both copies in the symboltable, then I think the
+proposal should be killed as soon as possible. If not sooner.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, February  5, 2003  3:40 AM
+
+> I think you need to keep around indefinitely both a "full view" of
+> the package and a "limited view" of the package.  Even after you
+> do a "full" compile, some units can still do "limited with" and should only
+> see the limited view.  What I would recommend is you treat them as
+> pretty much distinct units.
+
+In terms of language description, you're right, a unit that does a "limited
+with" must see the limited view even for a unit that has been fully compiled.
+
+However, the implementation you suggest might make sense for your compiler, it
+doesn't make sense for ours (or for Randy's if I understand him right).  We
+fundamentally depend on the invariant: 1 Ada unit = 1 Diana tree.  Changing this
+is not an option.  This means that if we see "limited with P" and P has been
+fully compiled, then we need to simulate/synthesize a limited view for P.
+
+For name resolution, this is simple enough.  When we see the name P.T we do a
+lookup of the string "T" in the identifier table for P.  The lookup has to
+succeed if and only if T is part of the limited view.  We would probably do that
+by examining the Diana tree for T.  Another option would be to store a bit "yes,
+I am part of the limited view" on the defining identifier for T.
+
+Once name resolution has been done, we will have access to the full tree for T.
+At this point we will need to behave as if T was incomplete.  I can think of at
+least 3 ways to achieve this in our compiler, but the simplest one is probably
+to use a predicate "is this an incomplete type?" where appropriate, and have
+that predicate determine whether visibility was obtained though a "limited
+with".  We already have such a predicate, but I'm pretty sure that we don't call
+it everywhere it would be needed.
+
+This certainly looks like work, but we are not talking man-years here.  And
+there is certainly no need to keep two trees for each unit.
+
+**************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, February  5, 2003  3:32 AM
+
+> Add a legality rule:
+>
+> A library_item mentioned in a limited_with_clause shall be a
+> package_declaration[, not a subprogram_declaration, generic_declaration,
+> or generic_instantiation].
+
+Why not generic_instantiation?
+1) not really different from a package declaration
+2) quite useful, since instantiations are commonly used for building objects with
+   multiple facets.
+
+Later you say:
+>We do not allow a limited_with_clause to mention a generic
+>instantiation, because that would require all kinds of semantic analysis
+>stuff, such as visibility.
+Well, the instantiation has been compiled at that point, so all visibility
+should be solved.
+Maybe worth some further investigation
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, February  5, 2003  3:59 AM
+
+The restriction is perfectly sensible.  We don't want to have to do any name
+resolution to build the limited view, and in order to determine what generic we
+are talking about, we would have to do a pretty extensive name resolution (use
+clauses, parent units, renamings, etc.).  Moreover, in order to build the
+instantiation, we would have to have compiled the specification of the generic
+already, but limited views cannot have compilation prerequisites (if they had,
+we could run into circularity problems).
+
+**************************************************************
+
+From: Robert A. Duff
+Sent: Wednesday, February  5, 2003  8:22 AM
+
+Tucker and I discussed this issue yesterday, and we decided that
+although it *is* troubling to make rules that cause package instances to
+be different from normal packages, it is not feasible to implement the
+proposal (in some compilers) without this restriction.
+
+If there's a cycle, then the instantiation might *not* have been
+compiled yet.  How about:
+
+    limited with A;
+    package B is new Some_Generic(...);
+
+    limited with B;
+    package A is new Some_Generic(...);
+
+It cannot be the case that A and B have both been *fully* compiled
+before each other.
+
+I really think a key feature of this proposal is that when the compiler
+sees "limited with X", it can determine the list of incomplete types in
+X in a purely syntactic manner.  It should not have to do any kind of
+heavy-duty semantic analysis.  It should not have to look at any source
+text outside of X.
+
+It's not *so* bad, because if you wanted to do cycles like the above,
+you can always break the cycle by adding more generic formal parameters.
+
+**************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, February  5, 2003  11:28 AM
+
+Yes. I see the problem, and I have sympathy for the poor compiler writers.
+
+But with my teacher's hat on, I don't feel very easy to explain that in some
+cases, an instantiation is not equivalent to a regular package.
+
+**************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, February  5, 2003  5:47 AM
+
+Pascal Leroy wrote:
+>...
+
+>
+> From a pedagogical standpoint it would seem simpler to say that "limited
+> with" works like "with", i.e. that "limited with P.C.D" is equivalent to
+> "with P, P.C, P.C.D".  Any other option is going to unnecessary confuse
+> users.
+>
+> So maybe the right answer is that if a package has a "limited with" of
+> itself it has no effect (but is not illegal).
+
+Yes, that is preferable.
+
+> Yes, I was thinking that use clauses and package renamings would be OK in
+> that context, although if they lead to problems we could disallow them.  But
+> I can't think of any problem at this point.
+
+I sent a note about this, titled "Restrictions on limited-with".
+Have you seen it?  Any comments?
+I think "use" clauses are a bad idea.
+Renaming is tricky, and needs careful thought.
+
+**************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, February  5, 2003  6:23 AM
+
+Yes, I saw it, but after sending the above message.  I agree that use clauses
+cause a Beaujolais-ish effect (maybe this should be named the Chianti effect ;-)
+and should be disallowed.  I also agree that renamings should probably be
+disallowed since they cause more trouble than they are worth.
+
+**************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, February  5, 2003  7:18 AM
+
+So far it seems to me that the limited-with discussion looks like it
+is very promising. I must say I was unhappy with the idea of furiously
+trying to get a resolution in Padua (and I was trying to figure out
+how to molest my schedule to attend :-) but now I am actually getting
+some confidence that
+
+a) this is going in the right direction
+b) there really is a good possibility of agreement
+
+Very encouraging :-)
+
+We will definitely try to prototype this in GNAT as soon as there is a
+reasonably well defined proposal.
 
 **************************************************************
 

Questions? Ask the ACAA Technical Agent