CVS difference for ai05s/ai05-0135-1.txt
--- ai05s/ai05-0135-1.txt 2009/05/26 23:46:24 1.7
+++ ai05s/ai05-0135-1.txt 2009/06/02 06:22:37 1.8
@@ -1,4 +1,4 @@
-!standard 4.1.3(12) 09-05-26 AI05-0135-1/04
+!standard 4.1.3(12) 09-05-27 AI05-0135-1/05
!standard 7.1(2)
!standard 7.1.3(7)
!standard 8.4(5/2)
@@ -311,41 +311,41 @@
If it is decided that integrated package renames are not wanted,
it would be easy to remove them from the proposal.
- As Erhard has pointed out, there are good reasons to consider this
- option. It is certainly possible to use integrated package renames
- to write code that is very difficult to read; this was already true
- of Ada83 use clauses, but integrated package renames seem to offer
- substantially greater potential for confusion.
-
- Integrated package renames also make possible a number of odd corner cases:
-
- limited with Foo;
- package P is
- use package Bar renames Foo;
- end P;
+As Erhard has pointed out, there are good reasons to consider this
+option. It is certainly possible to use integrated package renames
+to write code that is very difficult to read; this was already true
+of Ada83 use clauses, but integrated package renames seem to offer
+substantially greater potential for confusion.
- package Outer is
- package Inner is
- use package Outer_Rename renames Outer;
- end Inner;
- end Outer;
+Integrated package renames also make possible a number of odd corner cases:
+
+ limited with Foo;
+ package P is
+ use package Bar renames Foo;
+ end P;
+
+ package Outer is
+ package Inner is
+ use package Outer_Rename renames Outer;
+ end Inner;
+ end Outer;
- Finally, integrated package renames are not needed to solve any of
- the problems that provided the original motivation for introducing
- integrated packages.
-
- The wording changes need to delete integrated package renames from this AI
- would be straightforward. This would include:
- - eliminating the wording changes in 8.5.3
- - replacing "integrated package or package renaming" with
- "integrated package" throughout
- - eliminating references to integrated package renamings
- in the change appended after 8.4(11)
+Finally, integrated package renames are not needed to solve any of
+the problems that provided the original motivation for introducing
+integrated packages.
+
+The wording changes need to delete integrated package renames from this AI
+would be straightforward. This would include:
+ - eliminating the wording changes in 8.5.3
+ - replacing "integrated package or package renaming" with
+ "integrated package" throughout
+ - eliminating references to integrated package renamings
+ in the change appended after 8.4(11)
----
- Tuck suggests that the name of an integrated package rename
- should not itself become "use"-visible when the enclosing package is "use"d.
+ Tuck suggests that the name of an integrated package (whether a rename or
+ not) should not itself become "use"-visible when the enclosing package is "use"d.
Consider the following example (supplied by Tuck):
Text_IO, Sequential_IO, and Direct_IO each include
@@ -380,6 +380,21 @@
As an aside, note that the above example would be allowed if
"IO_Exceptions.Name_Error" were replaced with "Name_Error".
+ Tuck observes that this rule should "apply
+ to *all* integrated packages, not just integrated package
+ renames, since the same problem comes up when you
+ declare an integrated subpackage, or an integrated
+ generic instance. You really don't want the names of
+ the integrated packages cluttering up the namespace when
+ you do a "use" of the enclosing package, but you *do*
+ want them when trying to disambiguate where you would
+ be using a complete expanded name."
+
+ If there is general agreement on this point, then
+ the two alternatives described below should be
+ discarded because they only address the case of
+ an integrated package rename.
+
Another solution would be to allow anonymous integrated package
renames, as in
use package <> renames Ada.Io_Exceptions;
@@ -4111,31 +4126,31 @@
From: Steve Baird
Date: Thursday, April 23, 2009 10:37 AM
-> ... this paragraph should go right after 8.4(8) (it's not really
-> related to "potentially use-visible by selection", which can go
+> ... this paragraph should go right after 8.4(8) (it's not really
+> related to "potentially use-visible by selection", which can go
> later).
->
+>
Good point.
> ----
->
-> The main reason I was reading the above was that I was trying to
-> figure out what happens when the same declaration is use-visible (and
+>
+> The main reason I was reading the above was that I was trying to
+> figure out what happens when the same declaration is use-visible (and
> use-visible by
-> selection) by multiple paths. This is where the equivalence you give
-> at the beginning of the discussion breaks down (or something is
+> selection) by multiple paths. This is where the equivalence you give
+> at the beginning of the discussion breaks down (or something is
> getting very complicated). Consider the following:
->
+>
> package P1 is
> C : constant Boolean := True;
> end P1;
->
+>
> with P1;
> package P2 is
> use package P3 renames P1;
> end P2;
->
+>
> with P1, P2; use P1, P2;
> procedure M1 is
> begin
@@ -4143,18 +4158,18 @@
> ...
> end if;
> end M1;
->
-> One would like this to be legal, by analogy with a regular use clause.
+>
+> One would like this to be legal, by analogy with a regular use clause.
And we agree that it is legal, right?
> But use-by-selection starts getting messy:
->
+>
> with P1;
> package P4 is
> use package P1 renames Standard.P1;
> end P4;
->
+>
> with P1, P4; use P1, P4;
> procedure M2 is
> begin
@@ -4162,20 +4177,20 @@
> ...
> end if;
> end M2;
->
-> Is (1) OK? I suppose it is because the prefix P1 is directly visible,
+>
+> Is (1) OK? I suppose it is because the prefix P1 is directly visible,
> which hides the use-visible P4.P1.
->
+>
Right.
> But then try:
->
+>
> with P1;
> package P5 is
> use package P1 renames Standard.P1;
> end P5;
->
+>
> with P4, P5; use P4, P5;
> procedure M3 is
> begin
@@ -4183,13 +4198,13 @@
> ...
> end if;
> end M3;
->
-> Both P4.P1.C and P5.P1.C denote the same declaration, so one would
-> expect this to work. (That is how I read the proposed wording.) But it
+>
+> Both P4.P1.C and P5.P1.C denote the same declaration, so one would
+> expect this to work. (That is how I read the proposed wording.) But it
> isn't clear to me at all how that gets worked out from the non-overloadable prefixes.
-> (Currently, there can only be one interpretation of a non-overloadable
+> (Currently, there can only be one interpretation of a non-overloadable
> name, but here it seems that we have two.)
->
+>
This is ambiguous because the prefix of the name P1.C is ambiguous.
I believe the wording I suggested captures this correctly, and that this is consistent
@@ -4214,19 +4229,19 @@
Y : Integer := P1_Ren.X; -- illegal
-> One could argue that we don't need this complication, and declare (2)
-> to be ambiguous. But then you would risk eliminating declarations that
+> One could argue that we don't need this complication, and declare (2)
+> to be ambiguous. But then you would risk eliminating declarations that
> don't conflict with anything and that we need to see.
->
+>
> package P6 is
> V : Integer := 0;
> end P6;
->
+>
> with P6;
> package P7 is
> use package P1 renames Standard.P6;
> end P7;
->
+>
> with P4, P7; use P4, P7;
> procedure M4 is
> begin
@@ -4234,18 +4249,18 @@
> ...
> end if;
> end M4;
->
-> One would hope there is no ambiguity here (in (3)), as there is only
+>
+> One would hope there is no ambiguity here (in (3)), as there is only
> one C in the program. Again, this is what the wording appears to say.
>
No, I believe the prefix of the name "P1.C" is ambiguous and that this example should be
rejected. Certainly that was my intent and I believe the suggested wording captures that.
-> So it looks like *everything* is overloadable in a practical sense
-> (the compiler will have to treat every prefix that way at least). At
-> which point I wonder what the advantage of continuing to even have
-> non-overloadable declarations will be, since they'll no longer provide
+> So it looks like *everything* is overloadable in a practical sense
+> (the compiler will have to treat every prefix that way at least). At
+> which point I wonder what the advantage of continuing to even have
+> non-overloadable declarations will be, since they'll no longer provide
> any benefit in resolution or error correction.
I don't think so. I think the bad consequences you describe are based on a misunderstanding.
@@ -4396,9 +4411,9 @@
...
> However, what should the <something> be? Well, most natural would be:
> "use package IO_Exceptions renames Ada.IO_Exceptions;"
->
+>
> but now suppose you have:
->
+>
> with Ada.IO_Exceptions;
> with Ada.Text_IO;
> use Ada;
@@ -4410,9 +4425,9 @@
> exception
> when IO_Exceptions.Name_Error =>
> -- oops, this doesn't compile any more!
->
+>
> end What_Fun;
->
+>
Good point. I'll certainly include this example in the AI.
@@ -4423,7 +4438,7 @@
> But I suppose that depends on the details of the wording for
> how the contents of an integrated package rename (presuming we
> support them) become visible... Steve?
->
+>
Right.
The compilation error you mentioned above can be fixed by replacing
@@ -4520,9 +4535,9 @@
Our front end has no problem compiling this example.
> end Test;
->
-> I don't see why we would want "integrated packages" to work
-> differently, that would make a lot of additional work and would add
+>
+> I don't see why we would want "integrated packages" to work
+> differently, that would make a lot of additional work and would add
> confusion to users (which kind of use clause works how??).
I agree that integrated renames should work like regular renames from this point
@@ -4552,25 +4567,25 @@
From: Steve Baird
Sent: Friday, May 22, 2009 4:56 PM
-> I made an argument like this once (in terms of implementation
-> difficulty) and Steve convinced me that there is none because we're
-> not allowing anything new. This sounds new, since we get such
+> I made an argument like this once (in terms of implementation
+> difficulty) and Steve convinced me that there is none because we're
+> not allowing anything new. This sounds new, since we get such
> conflicts from renames with client use clauses:
->
+>
> package P is
> Obj : Natural;
> end P;
->
+>
> with P;
> package Q is
> package Inner renames P;
> end Q;
->
+>
> with P;
> package R is
> package Inner renames P;
> end R;
->
+>
> with Q, R;
> procedure Test is
> use Q.Inner, R.Inner;
@@ -4768,7 +4783,7 @@
> when Name_Error => null; -- Supposedly OK.
> end;
>
-> I want "integrated packages" to work exactly as if the declarations
+> I want "integrated packages" to work exactly as if the declarations
> are in the outer package, and this difference is aggravating.
But as Steve points out, this has always been legal with regular use- clauses on renamings.
@@ -4793,10 +4808,10 @@
From: Randy Brukardt
Sent: Tuesday, May 26, 2009 6:38 PM
-> It doesn't work differently for package *names*, but it works for the
-> contents of a package if it is "use"d via two different renames. Ada
-> is not a "name equivalent" language in the sense you imply. It is
-> "name equivalent" only if there are no renamings in the name, and you
+> It doesn't work differently for package *names*, but it works for the
+> contents of a package if it is "use"d via two different renames. Ada
+> is not a "name equivalent" language in the sense you imply. It is
+> "name equivalent" only if there are no renamings in the name, and you
> start from "Standard".
Sorry, but this last sentence is clearly False. And that is what I'm objecting
@@ -4814,15 +4829,15 @@
> procedure Test is
> use P, Q; -- "S" is canceled out here;
> -- packages are *not* a special case
->
+>
> use P.S, Q.S; -- But no cancellation occurs here.
> -- because P.S and Q.S denote
> -- the *same* package.
->
-> Package renamings would not work if they created a new set of
+>
+> Package renamings would not work if they created a new set of
> declarations of the components of the package.
-> We clearly want P.S.T and Q.S.T to denote the same declaration. If
-> for example, T is a type declaration, P.S.T and Q.S.T are the same
+> We clearly want P.S.T and Q.S.T to denote the same declaration. If
+> for example, T is a type declaration, P.S.T and Q.S.T are the same
> type.
I can't think of any legitimate reason to write a use clause of a renamed package in
@@ -4837,6 +4852,137 @@
****************************************************************
+From: Tucker Taft
+Sent: Tuesday, May 26, 2009 8:08 PM
+
+>> It doesn't work differently for package *names*, but it works for the
+>> contents of a package if it is "use"d via two different renames. Ada
+>> is not a "name equivalent" language in the sense you imply. It is
+>> "name equivalent" only if there are no renamings in the name, and you
+>> start from "Standard".
+>
+> Sorry, but this last sentence is clearly False. And that is what I'm
+> objecting to. If you had said:
+>
+> It is "name equivalent" only if there are no renamings {of packages}
+> in the name, and you start from "Standard".
+>
+> then you would have made a True statement. But why should packages get
+> this special treatment, and not renames of exceptions, or generics, or
+> subprograms, etc.? We have "Ada is a name equivalence language unless
+> the name is a renaming of a package".
+
+I am really confused by your world view on this one.
+I suspect someone else will have to pick up the discussion.
+
+But let me try one more time. Clearly renaming doesn't create a new entity,
+though it does represent a new declaration, and a new view, but of the same entity.
+This is independent of whether it is a package or any other kind of entity that
+allows renaming.
+
+Use-package clauses name a package *entity*, and it doesn't matter through which
+renaming they do so. Use-package clauses make certain *declarations* directly
+visible, those are the declarations that appear in the visible part of the use'd
+package entity. The declarations affected might be package (renaming) declarations,
+or any other kind of declaration, and they are all treated similarly -- package
+declarations aren't a special case.
+
+The *only* special case of which I am aware relative to "use" clauses is for the
+package "entity" that is named in the use clause. That seems as it should be.
+
+Now we can debate how this integrated package thing works, but I thought our
+model was that use'ing an outer package effectively does "use"s of all of the
+nested integrated packages. I have also proposed that the integrated package
+declarations are *not* made directly visible by "use"ing the enclosing package,
+sort of "in exchange" for their contents being made directly visible. This
+latter part is clearly up for debate, but doesn't seem related to your issue of
+"name equivalence."
+
+By the way, I wouldn't say Ada has "name equivalence,"
+but rather it has "declaration equivalence." That is, it really doesn't matter
+how you get to the declaration, but so long as two names denote the same declaration,
+directly or through a rename, you are talking about the same thing.
+
+Anyway, I get the sense I am missing the points you have been making, so I'll let
+someone else take up the discussion from here if you think I am still way off base.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, May 27, 2009 8:08 PM
+
+...
+> I am really confused by your world view on this one.
+> I suspect someone else will have to pick up the discussion.
+
+I'm just trying to figure out why some renames are different than others wrt use
+clauses. Apparently the only justification is "that's just the way it is".
+
+It doesn't pay to argue about it further, simply because we aren't likely to make
+any changes in this area, and surely we're not going to get more restrictive.
+
+> But let me try one more time. Clearly renaming doesn't
+> create a new entity, though it does represent a new
+> declaration, and a new view, but of the same entity.
+> This is independent of whether it is a package or any other
+> kind of entity that allows renaming.
+
+Correct.
+
+> Use-package clauses name a package *entity*, and it doesn't
+> matter through which renaming they do so. Use-package
+> clauses make certain *declarations* directly visible, those
+> are the declarations that appear in the visible part of the
+> use'd package entity. The declarations affected might be
+> package (renaming) declarations, or any other kind of
+> declaration, and they are all treated similarly -- package
+> declarations aren't a special case.
+
+You're saying that use clauses work on entities (not declarations), but they
+make declarations (not entities) visible. Yeah, *that's* consistent.
+
+It's clear to me from trying to make sense of the ASIS semantic subsystem that
+any rules based on declarations alone make no sense at all -- because Ada has
+lots of anonymous items that don't have declarations (well, I suppose they're
+part of some unrelated declaration, but that's more confusing than helpful) --
+and it has ways for entities to have multiple declarations. That way lies
+madness - and apparently that's where we are. (We'll get an opportunity to go
+into gory detail on the ASIS stuff, but not today...)
+
+> The *only* special case of which I am aware relative to "use"
+> clauses is for the package "entity" that is named in the use
+> clause. That seems as it should be.
+
+That's either too many or too few.
+
+...
+> By the way, I wouldn't say Ada has "name equivalence,"
+> but rather it has "declaration equivalence." That is, it
+> really doesn't matter how you get to the declaration, but so
+> long as two names denote the same declaration, directly or
+> through a rename, you are talking about the same thing.
+
+As I noted above, that way lies madness. I'm not sure if I'm the one that has
+gone mad (with Jean-Pierre's help vis-a-vis ASIS), but surely *someone* is
+insane here!
+
+Getting back to the original point: to say use-clause cancelation happens all
+of the time unless two package renames are involved makes no sense whatsoever.
+Either the cancelation should be canceled :-) whenever the same entity is referenced,
+or never. I'd prefer the latter, but the former is more compatible.
+
+> Anyway, I get the sense I am missing the points you have been
+> making, so I'll let someone else take up the discussion from
+> here if you think I am still way off base.
+
+As I said, it doesn't really matter at this point. This is clearly an insanity
+inherited from Ada 83, and never thought enough of to fix (unlike most of the
+other insanities of Ada 83). Doesn't pay to get too worked up over it, so I'm
+happy to agree to disagree (although I've still against further expansion of
+these bugs, so in the absence of a fix I'm not voting for any new forms of use clause).
+
+****************************************************************
+
From: Steve Baird
Sent: Tuesday, May 26, 2009 1:27 PM
@@ -4845,23 +4991,710 @@
****************************************************************
-From: Randy Brukardt
-Sent: Tuesday, May 26, 2009 6:38 PM
+From: Tucker Taft
+Sent: Tuesday, May 26, 2009 2:15 PM
+
+I had intended that the use-visibility rule would apply to *all* integrated
+packages, not just integrated package renames, since the same problem comes
+up when you declare an integrated subpackage, or an integrated generic
+instance. You really don't want the names of the integrated packages
+cluttering up the namespace when you do a "use" of the enclosing package,
+but you *do* want them when trying to disambiguate where you would be using
+a complete expanded name.
****************************************************************
+From: Steve Baird
+Sent: Tuesday, May 26, 2009 2:42 PM
+
+Tuck - Understood. Does the correction below fix the problem?
+
+Randy - here's a suggested update to the update (pending Tuck's ok):
+ 1) Replace
+ "Tuck suggests that the name of an integrated package rename
+ should not itself become ..."
+ with
+ "Tuck suggests that the name of an integrated package (whether a
+ rename or not) should not itself become ... "
+
+ 2) Add the following before the paragraph that begins
+ "As an aside ,,,":
+
+ Tuck observes that this rule should "apply
+ to *all* integrated packages, not just integrated package
+ renames, since the same problem comes up when you
+ declare an integrated subpackage, or an integrated
+ generic instance. You really don't want the names of
+ the integrated packages cluttering up the namespace when
+ you do a "use" of the enclosing package, but you *do*
+ want them when trying to disambiguate where you would
+ be using a complete expanded name."
+
+ If there is general agreement on this point, then
+ the two alternatives described below should be
+ discarded because they only address the case of
+ an integrated package rename.
+
+[This was done in version /05 - Editor.]
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, May 26, 2009 2:55 PM
+
+That's fine.
+
+****************************************************************
+
From: Randy Brukardt
-Sent: Tuesday, May 26, 2009 6:38 PM
+Sent: Tuesday, May 26, 2009 7:10 PM
+
+> Here are the updates to the AI that were discussed during the 5/20 call.
+
+You give the following example:
+
+> Integrated package renames also make possible a number of odd corner cases:
+>
+> limited with Foo;
+> package P is
+> use package Bar renames Foo;
+> end P;
+
+One would hope that this is illegal, because we don't allow any other "use"
+clauses on limited views of packages. I don't see any reason whatsoever for this
+to be different. (The problems shown in this example illustrate why that's the case.)
+
+----
+
+You give as an example:
+
+ package Pkg is
+ type T is tagged ... ;
+
+ use package Inner is
+ function Not_Primitive (X : T) return T;
+ end Inner;
+ end Pkg;
+
+and mention that you would like to be able to make the name Not_Primitive visible
+directly in Pkg. But this is exactly one of the sorts of effects that bothers me
+about this proposal. Clients cannot ignore the presence of the nested package, because
+its effects re-emerge periodically. This is one of those cases: the primitiveness changes,
+so for the purposes of deriving a type from T, you have to know the *real* structure of
+the package.
+
+----
+
+Similarly, consider another example from the AI:
+
+ with Some_Container_Generic;
+ package Pkg is
+ use package Inner is
+ type T is private;
+ private
+ ...;
+ end Inner;
+
+ use package I is new Some_Container_Generic (T);
+ end Pkg;
+
+if you have a limited with of Pkg:
+
+ limited with Pkg;
+ procedure Main is
+ Obj : access Pkg.T; -- Illegal!
+ Obj2 : access Pkg.Inner.T; -- Yuck.
+ begin
+
+the supposedly "integrated" package reappears.
+
+This also happens when there are use-conflicts, even if those conflicts are within a
+single package specification.
+
+----
+
+You can also name the inner package in a use-clause, giving visibility to only part
+of the supposedly "integrated" whole. This seems bad from the view of a client, which
+really wants to see a real, flat view of the package.
+
+Part of the trouble here is the name of this construct: there is nothing really
+"integrated" about these packages. It's really a way to force a use-clause on a client.
+If they were really "integrated", we would see none of the unusual effects seen here.
+
+----
+
+I realize that some differences from a fully flat package are going to be required (else
+you could just declare everything without the nested package). But some of these just seem
+outright wrong.
+
+I have to wonder if we can do better. I don't recall anymore why we switched to
+use-visibility for these things; it just seems wrong for many reasons. Perhaps there is
+some way to avoid that??
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, May 27, 2009 11:49 AM
+
+...
+> One would hope that this is illegal, because we don't allow any other "use"
+> clauses on limited views of packages. I don't see any reason
+> whatsoever for this to be different. (The problems shown in this
+> example illustrate why that's the case.)
+>
+
+It's not clear what this construct means, and that's the point (in the context of
+discussing whether integrated package renames are desirable). I agree that this
+probably should be illegal, but that doesn't fall out from the current wording - an
+explicit rule would be needed.
+
+> ----
+>
+> You give as an example:
+>
+> package Pkg is
+> type T is tagged ... ;
+>
+> use package Inner is
+> function Not_Primitive (X : T) return T;
+> end Inner;
+> end Pkg;
+>
+> and mention that you would like to be able to make the name
+> Not_Primitive visible directly in Pkg. But this is exactly one of the
+> sorts of effects that bothers me about this proposal. Clients cannot
+> ignore the presence of the nested package, because its effects
+> re-emerge periodically. This is one of those cases: the primitiveness
+> changes, so for the purposes of deriving a type from T, you have to know the *real*
+> structure of the package.
+>
+
+I agree, although I should point out that this example came up in a "real" context; there
+was a serious question about how to accomplish this effect (an implementation-defined
+Not_Primitive pragma was mentioned as a possible solution).
+
+Nobody is pretending that this construct produces identical results to doing the
+"integration" by hand (although it is interesting to note that trying to rewrite this
+particular example without using this new construct gets a little messy - I think a subtype
+declaration is required).
+
+> ----
+>
+> Similarly, consider another example from the AI:
+>
+> with Some_Container_Generic;
+> package Pkg is
+> use package Inner is
+> type T is private;
+> private
+> ...;
+> end Inner;
+>
+> use package I is new Some_Container_Generic (T);
+> end Pkg;
+>
+> if you have a limited with of Pkg:
+>
+> limited with Pkg;
+> procedure Main is
+> Obj : access Pkg.T; -- Illegal!
+> Obj2 : access Pkg.Inner.T; -- Yuck.
+> begin
+>
+> the supposedly "integrated" package reappears.
+>
+
+I think the problems with limited views of integrated packages and package renames are
+dwarfed to the point of insignificance by the existing treatment of limited views of
+instantiations and of ordinary package renames (which I am not arguing against).
+
+Limited views (technical term) provide a very limited view (common English) of things.
+
+That's ok, we've accepted that.
+
+As the AI mentions, we do have the option of relaxing this limitation and allowing a
+limited view of an integrated package to be integrated in some cases (not for renames,
+not for instances).
+
+> This also happens when there are use-conflicts, even if those
+> conflicts are within a single package specification.
+>
+> ----
+>
+> You can also name the inner package in a use-clause, giving visibility
+> to only part of the supposedly "integrated" whole. This seems bad from
+> the view of a client, which really wants to see a real, flat view of the package.
+
+The point is that the client has the option of seeing a flat view of the package.
+If the client wants to explicitly disambiguate a name by referencing the inner package,
+that's up to the client. If you want to disallow this, it could, I suppose, be detected
+by some coding-standard-enforcement tool; that is outside of the scope of the language
+definition.
+
+> Part of the trouble here is the name of this construct: there is
+> nothing really "integrated" about these packages. It's really a way to
+> force a use-clause on a client. If they were really "integrated", we
+> would see none of the unusual effects seen here.
+
+This is a relatively lightweight solution. The fact that it is based on use-clauses
+definitely does show through in some cases.
+
+On the other hand, if this solves the "exporting a private type and a container thereof"
+problem (and I think it does), then that alone is a strong argument for including this
+feature.
+> ----
+>
+> I realize that some differences from a fully flat package are going to
+> be required (else you could just declare everything without the nested
+> package). But some of these just seem outright wrong.
+>
+> I have to wonder if we can do better. I don't recall anymore why we
+> switched to use-visibility for these things; it just seems wrong for many reasons.
+> Perhaps there is some way to avoid that??
+
+It's often true that as we come to see the problems with one approach in more detail,
+the path that we didn't take starts looking more and more attractive.
+
+As you noted, the early discussions of this AI were based on implicit rename/subtype
+declarations and had nothing to do with use clauses.
+
+One problem with that approach was collisions. Implicit declarations of non-overloadable
+constructs would have taken some work to straighten out.
+
+Use-visibility provided a reasonable approach to resolving these issues that was already
+a well-defined part of the language,
+
+If you think we should revive the rename/subtype approach or even pursue an entirely new
+solution, either
+ a) provide a reasonably specific alternative that we can discuss or
+ b) get more of a consensus from the group that we want to
+ at least explore some other alternative and then I'll
+ try to write something up.
+
****************************************************************
From: Randy Brukardt
-Sent: Tuesday, May 26, 2009 6:38 PM
+Sent: Wednesday, May 27, 2009 9:09 PM
+
+...
+> It's not clear what this construct means, and that's the point (in the
+> context of discussing whether integrated package renames are desirable).
+> I agree that this probably should be illegal, but that doesn't fall
+> out from the current wording - an explicit rule would be needed.
+
+Yes, of course such a rule is needed. I've been saying that repeatedly (see my mail
+of December 18th, 2008 and March 12, 2009), and you've never added the rule to the
+actual AI. Please do so (or at least explain what it means to not have it).
+
+Besides, this is a lousy example of why it is not desirable to allow renames. The
+problem is simply that you have declarations appearing in a scope with no sane way to
+determine where they come from.
+
+But that also happens for instantiations, and I no longer see much difference between
+"integrated" renamed packages, and "integrated" instantiations. So the reason *I* was
+objecting to renames has become OBE (can't speak for others); the more important
+question for me is whether this whole idea sacrifices too much readability. (At least
+readability in the absence of a fancy IDE.)
+
+...
+> Limited views (technical term) provide a very limited view (common
+> English) of things.
+True enough; I've been trying to explain my discomfort with this proposal with things
+that are different, but they don't necessarily seem important. That means my overall point
+is getting lost.
+
+...
+> > You can also name the inner package in a use-clause, giving
+> > visibility to only part of the supposedly "integrated" whole. This
+> > seems bad from the view of a client, which really wants to see a real, flat view of the package.
+>
+> The point is that the client has the option of seeing a flat view of
+> the package. If the client wants to explicitly disambiguate a name by
+> referencing the inner package, that's up to the client. If you want to
+> disallow this, it could, I suppose, be detected by some
+> coding-standard-enforcement tool; that is outside of the scope of the
+> language definition.
+
+OK, here is the crux of the problem. As a package designer, I want to *limit* the ways that
+the client can refer to things. Otherwise, package maintenance becomes much harder. For
+instance, with this notion of "integrated" packages, it would be impossible to change back
+to a "flat" structure (because there can be references to the "integrated" package. Nor can
+you change to "integrated" packages from a "flat" structure without introducing incompatibilities.
+That can be bad.
+
+> > Part of the trouble here is the name of this construct: there is
+> > nothing really "integrated" about these packages. It's really a way
+> > to force a use-clause on a client. If they were really "integrated",
+> > we would see none of the unusual effects seen here.
+>
+> This is a relatively lightweight solution. The fact that it is based
+> on use-clauses definitely does show through in some cases.
+
+Yes, but you've missed my point completely. If you had called it something else (say
+"automatically used packages"), I wouldn't have quite the same objections. The *name*
+"integrated packages" gives an expectation of seamless merging; that isn't happening here,
+so the *name* is causing (unreasonable?) expectations.
+
+> On the other hand, if this solves the "exporting a private type and a
+> container thereof" problem (and I think it does), then that alone is a
+> strong argument for including this feature.
+
+Surely we need *some* solution to this problem, but I'm not certain this one is better than
+any of the other (now rejected) ideas.
+
+...
+> As you noted, the early discussions of this AI were based on implicit
+> rename/subtype declarations and had nothing to do with use clauses.
+>
+> One problem with that approach was collisions. Implicit declarations
+> of non-overloadable constructs would have taken some work to
+> straighten out.
+
+I think such collisions should simply be illegal. Tough if that prevents declaring two container
+instances this way; we don't want homographs.
+
+> Use-visibility provided a reasonable approach to resolving these
+> issues that was already a well-defined part of the language,
+
+Yes, I know, I was a strong advocate for pursuing this solution.
+
+> If you think we should revive the rename/subtype approach or even
+> pursue an entirely new solution, either
+> a) provide a reasonably specific alternative that we can discuss or
+> b) get more of a consensus from the group that we want to
+> at least explore some other alternative and then I'll
+> try to write something up.
+
+Well, you know I don't have time to do either of these before the Brest meeting.
+But I'm definitely going to try to block progress on this one until I have time
+to do (a) or someone does (b). This proposal does not "feel right" to me.
+
****************************************************************
From: Randy Brukardt
-Sent: Tuesday, May 26, 2009 6:38 PM
+Sent: Wednesday, May 27, 2009 10:06 PM
+> This proposal does not "feel right" to me.
+
+Let me add that the reasons are not that obvious and surely this is no
+reflection on the author of the proposal. (Part of the reason for complaining
+now is the hope that Tucker or I or someone will have an inspiration before the
+next meeting, that won't happen if the proposal is thought to be "good enough".)
+
+Anyway, my concerns are almost exclusively focused on the client's view of a
+package. I don't much care how complex the creation of a specification is, or
+how much change is necessary to do something in the specification, so long as
+the client view is controllable. But I would like the client view to be as close
+as possible to a "flat" structure with all of the interesting declarations
+appearing to exist in the outermost package.
+
+This proposal comes close but doesn't quite make it.
+
+---
+
+One example that I've been thinking about is the proposed generic to provide
+iterators. If we do decide to define that "magic" generic, we will need to
+rearrange the Ada.Containers packages a lot to use it. But that rearrangement
+would seem to be incompatible in a number of ways, and limiting on
+implementation strategies to boot.
+
+To refresh, assume that we have a magic iterator generic (this is simplified for
+this example, as are the following packages) and we have Steve's "integrated
+packages":
+
+ generic
+ type Cursor is private;
+ No_Element : in Cursor;
+ package Ada.Iterator_Interfaces is
+ type Basic_Iterator is limited interface;
+ function First (Object : Basic_Iterator) return Cursor;
+ function Next (Object : Basic_Iterator; Position : Cursor) return Cursor;
+ end Ada.Iterator_Interfaces;
+
+[Note that the exact form of this generic doesn't matter much in terms of what
+rearrangements need to be done to the Ada.Containers packages.]
+
+Now, we currently have:
+
+ generic
+ type Element_Type is private;
+ package Ada.Containers.Doubly_Linked_Lists is
+ type List is tagged private;
+ type Cursor is private;
+
+ Empty_List : constant List;
+ No_Element : constant Cursor;
+
+ function Is_Empty (Container : List) return Boolean;
+ procedure Clear (Container : in out List);
+ function Element (Position : Cursor)
+ return Element_Type;
+ ...
+ private
+ ... -- not specified by the language
+ end Ada.Containers.Doubly_Linked_Lists;
+
+In order to add Basic_Iterator visibly to type List, we'll have to rearrange
+this into using at least one nested package. The simplest I can come up with is:
+
+ with Ada.Iterator_Interfaces;
+ generic
+ type Element_Type is private;
+ package Ada.Containers.Doubly_Linked_Lists is
+ use package Cursors is
+ type Cursor is private;
+ No_Element : constant Cursor;
+ private
+ ... -- not specified by the language
+ end Cursors;
+
+ package Iterators is new
+ Ada.Iterator_Interfaces (Cursors, No_Element);
+
+ type List is new Iterators with private;
+
+ Empty_List : constant List;
+ function Is_Empty (Container : List) return Boolean;
+ procedure Clear (Container : in out List);
+ function Element (Position : Cursor)
+ return Element_Type;
+ ...
+ private
+ ... -- not specified by the language
+ end Ada.Containers.Doubly_Linked_Lists;
+
+Limited with incompatibilities don't matter in this case, as you can't get a
+limited view of a generic unit.
+
+Primitiveness incompatibilities are definitely in evidence, but I do have to
+wonder if it matters. In particular, if you derive from type Cursor currently,
+you will inherit function Element. But you will no longer inherit that routine
+with this rearrangement. I don't know how significant that is (I would suggest
+it is not very significant).
+
+Naming incompatibilities don't seem to be a problem with this example. They
+could be if we wanted to remove the "integrated" nested package (as someone
+could have named it explicitly in a use clause or in an expanded name). That's
+not likely to be an issue in this case.
+
+Since there is only two entities (plus the inherited "=") in the nested
+packages, we could just rename them and not need any special construct at all.
+But we'd still have the incompatibilities. (I did not expect this result when I
+started writing this message.)
+
+But there still is a significant issue. While we are not specifying what goes
+into the private parts, we do need to be able to writ them. A cursor needs a
+reference to a node and to the full container (the List in this example). The
+node probably could be defined in the private part of package Cursors, but we
+can't define a reference to List in the private part -- it hasn't been declared
+yet! And it *can't* be declared yet, because it depends on the interface that we
+haven't yet created.
+
+One way to workaround this problem is to use a Taft-amendment type in the
+private part of Cursors. But we can't complete that with the type List itself;
+we'd have to use a derived type. And that is obnoxious, forcing many junk type
+conversions. Even using class-wide types won’t get rid of those conversions,
+because they would be toward the root of the tree.
+
+Another possible workaround would be to clutter the spec with an incomplete type
+List before the nested package. But that could not be completed with the private
+extension List, so we would still end up with the same problem.
+
+In conclusion, this rearrangement works, has some client incompatibility (but it
+probably isn't important), but forces a major amount of junk type conversions in
+the body of the package. Of course, this is only one example, and it would be
+nice to look at additional examples in the future.
+
****************************************************************
+From: Tucker Taft
+Sent: Thursday, May 28, 2009 2:12 PM
+
+> Another possible workaround would be to clutter the spec with an
+> incomplete type List before the nested package. But that could not be
+> completed with the private extension List, so we would still end up with the
+> same problem.
+
+This particular problem seems fixable. The requirement that an incomplete type
+declaration be completed with a full_type_declaration seems arbitrary. There
+seems no inherent reason that it couldn't be completed with a private type or
+private extension declaration.
+
+
+The incomplete types produced from a "limited with" allow that, so the mechanism
+will be needed in Ada 2005 to handle such a completion anyway.
+
+> In conclusion, this rearrangement works, has some client
+> incompatibility (but it probably isn't important), but forces a major
+> amount of junk type conversions in the body of the package. Of course,
+> this is only one example, and it would be nice to look at additional examples
+> in the future.
+
+Normally I would have expected that almost the entire package would be included
+in an "integrated" package, and then this big nested package would be followed by
+various generic instantiations. But you have illustrated a case where that doesn't
+work, because you want one of the types to be built on the result of a generic
+instantiation. I wonder how common that is.
+
+How would you do it without this feature? As you point out, the integrated package
+is mostly just a short-hand for a bunch of renames, and in this case, there aren't
+that many. Hiding the nested package name automatically from use-visibility might
+be a helpful advantage of the proposed feature ;-).
+
+It does seem the ability to define an incomplete type that is completed by a partial
+view would be helpful, independent of this proposal.
+
+I wonder if your "magic iterator" generic has this problem in general, and perhaps
+it needs to be *defining* a cursor type, rather than taking it as a parameter. Or
+is it the fact that we want the container to be usable as an iterator? I think that
+is probably a bad idea in general, as it is inherently problematic to have the container
+carry some state about a particular iterator over the container. I understand the
+desire for a *syntax* approximating:
+
+ for Element in Container loop
+ ...
+ end loop;
+
+But I see no requirement that this means we somehow have an iterator built into the
+Container itself. Also, we would certainly want to allow multiple tasks to iterate
+over a Container in parallel, I would think, or to allow nested iterators such as:
+
+ for Left in Container loop
+ for Right in Container loop
+ Try_Pair(Left, Right);
+ end loop;
+ end loop;
+
+I think the above *syntax* should always presume there is an anonymous iterator object
+created, and that is what carries the state of the iteration.
+
+In any case, I wonder whether it is the strange nature of this generic that is creating
+the problem, or is there a common need to be able to define in a single package two
+recursively-dependent types one of which is based on a generic instantiation of the other.
+I suppose this is a very hard question to answer...
+
+Thanks for the example!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, May 28, 2009 2:49 PM
+
+...
+> This particular problem seems fixable. The requirement that an
+> incomplete type declaration be completed with a full_type_declaration
+> seems arbitrary. There seems no inherent reason that it couldn't be
+> completed with a private type or private extension declaration.
+> The incomplete types produced from a "limited with" allow that, so the
+> mechanism will be needed in Ada 2005 to handle such a completion
+> anyway.
+
+Yes, I in fact wrote this up originally assuming that such completions were
+allowed. But before making a fool out of myself, I looked up the actual rules
+and changed this part accordingly.
+
+It would still clutter the spec a bit with an extra type declaration that
+doesn't really have anything to do with anything other than the implementation,
+but not a major problem overall.
+
+> > In conclusion, this rearrangement works, has some client
+> > incompatibility (but it probably isn't important), but forces a
+> > major amount of junk type conversions in the body of the package. Of
+> > course, this is only one example, and it would be nice to look at
+> additional examples in the future.
+>
+> Normally I would have expected that almost the entire package would be
+> included in an "integrated" package, and then this big nested package
+> would be followed by various generic instantiations. But you have
+> illustrated a case where that doesn't work, because you want one of
+> the types to be built on the result of a generic instantiation. I
+> wonder how common that is.
+
+No idea. It seems to need interfaces to make much sense, so it would mainly
+come up in new code.
+
+> How would you do it without this feature? As you point out, the
+> integrated package is mostly just a short-hand for a bunch of renames,
+> and in this case, there aren't that many.
+> Hiding the nested package name automatically from use-visibility might
+> be a helpful advantage of the proposed feature ;-).
+
+I was surprised to find out that it doesn't seem to matter much either way; the key
+is to use the nested package. Making it "integrated" is just icing.
+
+> It does seem the ability to define an incomplete type that is
+> completed by a partial view would be helpful, independent of this
+> proposal.
+
+Yes, I think so.
+
+> I wonder if your "magic iterator" generic has this problem in general,
+> and perhaps it needs to be *defining* a cursor type, rather than
+> taking it as a parameter.
+
+I don't know how that could work, given that container cursors include a reference
+to the container object. I suppose the entire thing could be created as a mix-in generic
+(adding to the container directly), but that seems annoying (isn't that exactly the sort
+of thing that interfaces were created to avoid?).
+
+> Or is it the fact that
+> we want the container to be usable as an iterator? I think that is
+> probably a bad idea in general, as it is inherently problematic to
+> have the container carry some state about a particular iterator over
+> the container.
+
+I strongly agree with this, but you need to convince Ed. :-) Maybe the rest of
+your message will help.
+
+> I understand the desire for a *syntax* approximating:
+>
+> for Element in Container loop
+> ...
+> end loop;
+
+I had proposed
+ for Element in Container.Iterator loop
+ ...
+ end loop;
+(where "Iterator" is a function returning an anonymous iterator object).
+Since we're using that same sort of model for accessors (there is an "extra"
+discriminant reference in those), I don't see the problem. But of course, I
+was always happy with this formulation, it is other people that were not.
+
+> But I see no requirement that this means we somehow have an iterator
+> built into the Container itself. Also, we would certainly want to
+> allow multiple tasks to iterate over a Container in parallel, I would
+> think, or to allow nested iterators such as:
+>
+> for Left in Container loop
+> for Right in Container loop
+> Try_Pair(Left, Right);
+> end loop;
+> end loop;
+>
+> I think the above *syntax* should always presume there is an anonymous
+> iterator object created, and that is what carries the state of the
+> iteration.
+
+With the accessor proposal, you have to write a single extra selection; that
+seems fine to me for iterators, too. Since it would not be surprising to use
+both of them together, it would actually be kinda weird to have simpler syntax
+for the iterator and not the accessor:
+
+ for Cursor in Container.Iterator loop
+ Container.Accessor(Cursor).Element.Component := 10;
+ end loop;
+
+> In any case, I wonder whether it is the strange nature of this generic
+> that is creating the problem, or is there a common need to be able to
+> define in a single package two recursively-dependent types one of
+> which is based on a generic instantiation of the other. I suppose
+> this is a very hard question to answer...
+
+I would expect a similar problem any time that you wanted to define an interface
+that needs customization with some properties. But it is hard to tell for sure, other
+than to say that designers are clever and come up with structures that no one expects.
+
+****************************************************************
Questions? Ask the ACAA Technical Agent