CVS difference for ai05s/ai05-0138-1.txt

Differences between 1.5 and version 1.6
Log of other versions for file ai05s/ai05-0138-1.txt

--- ai05s/ai05-0138-1.txt	2009/05/19 22:42:13	1.5
+++ ai05s/ai05-0138-1.txt	2009/06/09 05:02:38	1.6
@@ -4080,10 +4080,12 @@
 For a static check (and its associated dynamic part) for the Object Obj of an
 access attribute, the following rules hold:
 
-* The check succeeds if Obj is (part of) a parameter of the function. (That is, returning
-  'Access of a parameter or a part of a parameter is always legal for accessibility purposes.)
-* The check succeeds if the master that elaborated the function is deeper than Obj. (You can
-  return the 'Access of any object that is visible outside of the function.)
+* The check succeeds if Obj is (part of) a parameter of the function. (That is,
+  returning 'Access of a parameter or a part of a parameter is always legal for
+  accessibility purposes.)
+* The check succeeds if the master that elaborated the function is deeper than Obj.
+  (You can return the 'Access of any object that is visible outside of the
+  function.)
 * Otherwise the check fails. (Can't return 'Access of local objects.)
 
 
@@ -5323,6 +5325,94 @@
 
 ****************************************************************
 
+From: Steve Baird
+Sent: Thursday, March 5, 2009  7:18 PM
+
+>     type Nested is new Non_Nested with ...;
+>     overriding function Blah (...) return access Non_Nested;
+>
+> Should the accessibility level of the access Non_Nested be that of the
+>root  type?
+
+Should this example even be legal?
+
+If you don't want dynamic checks, then don't you have to statically prohibit
+the various problematic scenarios which AI05-0051 resolves with dynamic checks?
+
+Or am I being too hasty in jumping to the conclusion that the elimination of
+dynamic access checks is one of the consequences of this proposal?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, March 5, 2009  7:34 PM
+
+I was just going to mention the same thing: Bob needs to read and understand as
+best he can the problems noted in AI05-0051-1. That's because fixing those
+problems is *not* optional; we can't leave the language broken! All of the
+other changes that have been discussed *are* optional.
+
+I did propose a way to convert AI05-0051-1 to all static checks, but I didn't
+think it was appropriate in all cases. It essentially depended on thinking
+similar to Bob's: the accessibility has to be that of a root type.
+The problem with that is that if you are actually returning an access type
+(as opposed to something that is just "return-by-reference", that pretty
+much prevents using any nested extensions. I don't see how that could fly
+in general (even though I personally would be happy to limit anonymous
+access types as much as possible).
+
+****************************************************************
+
+From: Bob Duff
+Sent: Thursday, March 5, 2009  7:39 PM
+
+> Should this example even be legal?
+
+I don't know.
+
+Note that with the 'Ref proposal, we have more freedom to make troublesome
+things illegal.
+
+> If you don't want dynamic checks, then don't you have to statically
+> prohibit the various problematic scenarios which AI05-0051 resolves
+> with dynamic checks?
+
+I don't understand AI05-0051.  That's why I don't like it -- I fear programmers
+are already overwhelmed by the complexity in this area, and AI05-0051
+exacerbates the problem.
+
+> Or am I being too hasty in jumping to the conclusion that the
+> elimination of dynamic access checks is one of the consequences of
+> this proposal?
+
+I think elimination of dynamic accessibility checks is one of the consequences
+of this proposal.  I realize that's a radical notion.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, March 5, 2009  8:24 PM
+
+...
+> I don't understand AI05-0051.  That's why I don't like it -- I fear
+> programmers are already overwhelmed by the complexity in this area,
+> and AI05-0051 exacerbates the problem.
+
+Actually, it is very simple: the accessibility of the ultimate use of the
+function result determines its accessibility. It's actually a rather cool model,
+in that I've had a hard time punching holes in it. OTOH, I really don't want to
+see more dynamic accessibility if there is a sane alternative.
+
+But that isn't particularly relevant. You *have to* understand the problems
+noted in AI05-0051-1 so that you can propose a solution to them. If you can't
+propose such a solution, we really can't go any further with your idea, because
+the *language is broken* as it currently stands -- functions can return objects
+that don't exist at the call site. That can't remain true (unless we're willing
+to just declare anonymous access returns as erroneous - which sounds like
+abandoning all hope).
+
+****************************************************************
+
 From: Bob Duff
 Sent: Thursday, March 5, 2009  5:21 PM
 
@@ -5406,31 +5496,3914 @@
 Why would you ever use this in a generic
 
 ****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, March 5, 2009  7:19 PM
+
+Good question. Let me rephrase it as "why would you ever use this anywhere?".
+Surely the answer to that is the same as in the generic (I don't find anything
+all that special about generic bodies).
+
+Personally, I think we should spend our efforts on making the existing (named)
+access types safer (dangling pointer detection/prevention) and more functional
+(more storage management options). I don't see any compelling reason to use any
+form of anonymous access types, especially as modern programs should be using
+less of access types in general (as they make it harder to write multitask
+programs and harder to prove all programs).
+
+****************************************************************
 
-*** Thread continues in ARG: "Anonymous access types" *** - RLB
+From: Robert Dewar
+Sent: Thursday, March 5, 2009  7:31 PM
 
-From: Bob Duff
-Sent: Thursday, March 5, 2009  7:51 AM
+> Good question. Let me rephrase it as "why would you ever use this
+> anywhere?". Surely the answer to that is the same as in the generic (I
+> don't find anything all that special about generic bodies).
+
+No, I don't think so in practice ...
+
+> Personally, I think we should spend our efforts on making the existing
+> (named) access types safer (dangling pointer detection/prevention) and
+> more functional (more storage management options). I don't see any
+> compelling reason to use any form of anonymous access types,
+> especially as modern programs should be using less of access types in
+> general (as they make it harder to write multitask programs and harder to prove all programs).
+
+The one case I find useful is where you have a very general access type and you
+want different people to share it.
+
+Consider the String_Access in Unbounded_String, it is really ugly that this is
+declared in the Unbounded_String spec to me. In the GNAT runtime we have two
+declarations of String_Access, one in System.Strings that everyone shares
+*except* for the spec of Unbounded_String which has a separate one. I would
+write String'Access in this spec.
+
+And I would not need System.Strings.
+
+I don't see ever needing 'Access on a generic formal
+
+(of course it is confusing we are calling this 'Access in this discussion :-)
+:-))
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, March 5, 2009  8:19 PM
+
+...
+> > We actually considered something something like this during the Ada
+> > 2005 work (I forget the name it had). But we ran into the infinite
+> > regress
+> > problem:
+> >
+> >     Integer'Access'Access
+> >
+> > and so on. That makes a lot of trouble for compilers (like
+> > Rational's) that materialize everything in their symboltable, since
+> > it simply is not possible to do that.
+>
+> Implementation difficulty is important, but I think usefulness for the
+> user, and simplicitly of the language, should trump that, at least in
+> this case.
+
+<rant> The *user* shouldn't be using any access types in new code (of any kind),
+unless they're implementing a new container or ADT. And even then, they should
+only use them in the private part/body.</rant>
+
+> I find it hard to believe that implementing T'Ref'Ref'Ref...
+> is _impossible_ in any compiler.  In GNAT, I don't even think it's all
+> that hard.
+
+I don't think it would be *impossible* in Janus/Ada, but it would mean
+abandoning much of our philosophy and some invariants. In particular, the type
+portion of the symbol table would balloon to at least 4 times its current size
+(at least on programs that used this feature). That would directly contradict
+our stated #1 goal of minimizing space usage, both at compile-time and run-time.
+
+I realize that in these days of more plentiful memory, that is not a popular
+goal (maybe even pointless). However, if we abandoned that goal completely,
+there would no longer be any justification for keeping Janus/Ada around: it can
+never be as good at creating *fast* programs as GCC, nor could it ever have as
+many features/tools/etc as GNAT. (This is the same reason that I continue to
+stick to generic code sharing, despite the pain it causes -- we need at least
+someone showing alternative things that are possible.)
+
+Thus, this would be a serious pain to implement in Janus/Ada -- except I can't
+imagine doing it absent a lot of customer demand. It just seems completely
+pointless.
+
+Bob had said long ago:
+
+> Franco and Quentin have taught over 100 students object-oriented
+> programming in Ada, and they say that it is extremely important to fix
+> these problems for Ada 2012.
+
+And Robert said:
+
+> I accept that the OO folks need them to prevent unnecessary
+> conversions (I don't understand enough to appreicate this first hand,
+> but it's fine if people tell me that)
+
+I don't understand this well enough either. But I am not willing to put features
+into Ada simply because a few people make a claim that no one seems to be able
+to understand!
+
+I would really like to understand *exactly* what problems that they are running
+into that cannot be better solved by eliminating the access types from the O-O
+programs. I know I asked Franco this explicitly back in November, and his answer
+was not responsive. A quote: "As for "doing OO without access types" as
+suggested by Randy, that's simply impossible in practice if you want to use
+dynamic dispatching." The problem is that that statement is not remotely true,
+you can do all of the dynamic dispatching you want using indefinite containers
+to hold class-wide objects. Moreover, Claw is totally about dynamic dispatching
+(for callbacks), but there are very few interfaces that use access types, and
+many of our example programs use statically allocated objects. Yes, there is a
+single named access type internally to Claw, but never any allocators,
+deallocators, conversions, or any of the other issues that are claimed to be
+important.
+
+(If Ada allowed stand-alone classwide objects and components, the situation
+would be even more clear-cut. I'd prefer doing that to messing anymore with
+access types. It would be fairly easy to do in Janus/Ada, but I realize that
+allocate-the-max compilers might have a tough time. Anyway, you can use a Holder
+container for those things, but I understand that is not completely ideal. But
+we could potentially change the language so that use of containers is easier
+rather than access types.)
+
+So I continue to see that people are trying to force the bad habits of other
+languages into Ada. A better choice would be see how best to do it in Ada. That
+means showing the *problem* (in the abstract), and letting me and others see
+what the best solutions are. All I've been hearing is "it's too hard to write
+our programs in Ada 2005", without any explanation as to why that is. That makes
+it impossible to see if there is a real problem or just bad methodology.
+
+I'm perfectly willing to believe that I'm wrong. But no one wants to explain
+why.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, March 5, 2009  9:23 PM
+
+> <rant> The *user* shouldn't be using any access types in new code (of
+> any kind), unless they're implementing a new container or ADT. And
+> even then, they should only use them in the private part/body.</rant>
+
+I find that a very peculiar rant indeed, I strongly disagree, I don't particular
+want to argue the point, just to register that the above is not received fact,
+but rather personal opinion that is definitely NOT shared by all.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, March 5, 2009  10:12 PM
+
+I *did* mark it with <rant>!
+
+The quickie explanation: Exporting access types from an ADT (abstract data type)
+greatly constrains the storage management choices of the client. They can't let
+a container manage the storage at all (even if they put the access type into the
+container, they'd still have to manage the storage). And it makes using
+stack-based allocation (that is, ordinary variables) much less convenient.
+
+If the ADT wants to manage storage itself, it has to use some sort of controlled
+handles in order to ensure that the storage is freed appropriately and the like.
+Again, no access types exported.
+
+If the client wants to use an access type and dynamic storage management, let
+then declare the access type themselves in an appropriate place.
+
+For a package that is an AST (abstract state machine), objects usually aren't
+exported at all. So again there is no reason to export access types.
+
+I suppose you might want to export access types in packages that are neither
+ADTs nor ASTs (that is, don't export private types of some sort), but these are
+likely to be highly coupled and thus are generally considered bad.
+
+Returning an access to an existing object in an ADT or AST is unsafe. There is
+no way in Ada to ensure that the object does not get destroyed while someone is
+holding an access to it - no matter who (the client or the ADT itself) is doing
+the storage management, there is no way to prevent copying such an access into a
+long-lived place (which makes the safety problem much worse), and there is no
+way to inform the ADT that the access is no longer needed. [I'd like to find a
+solution to some of these issues, whether it uses access types or not, but all
+of the proposals I've seen makes this problem worse.]
+
+You could use access types in an ADT *iff* you have guaranteed garbage
+collection and thus simply could completely forget about storage management. But
+that's some other language, not Ada.
+
+The net is that I don't see much good reason for visible access types in new
+code. (Under the hood in the implementation is a different story.) And thus I
+don't see much reason for making them easier to use (as opposed to safer).
+
+I realize that I hold a minority view here, and I would like to have a better
+understanding of why. But no one seems able to come up with a counter-argument
+to the above points, they just say "I disagree" and stop the conversation. It's
+almost like everyone has given up on allowing the client any flexibility in
+structuring programs. (I saw the same sort of thing in the old MFC libraries,
+but I blamed that on C-think. Perhaps it is something deeper?)
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Friday, March 6, 2009  12:34 PM
+
+> The quickie explanation: Exporting access types from an ADT (abstract data
+> type) greatly constrains the storage management choices of the client.
+> They can't let a container manage the storage at all (even if they put
+> the access type into the container, they'd still have to manage the
+> storage). And it makes using stack-based allocation (that is, ordinary
+> variables) much less convenient.
+
+This is a reasonable viewpoint for high level ADT's with approrpiate high level
+interfaces, but Ada is about low level code too. As reasonable examples of
+access type use, consider Interfaces.C.Strings. char_array_access. Sure you
+could make this a high level ADT, but that would be bad design in this case.
+Another example is indeed String_Access in unbounded strings, no point in
+dressing that one up in some fancy interface.
+
+Not all the world is containers!
+
+****************************************************************
+
+From: Ed Schonberg
+Sent: Friday, March 6, 2009  12:44 PM
+
+No, but it is a reasonable goal to raise the level of the language by having
+containers that take care of more storage management. I'm in sympathy with
+Randy's goals : it is a good thing to make pointers less visible where possible.
+After all, high-level languages don't have them!
+
+The problem is that high-level languages have garbage collection, and in their
+absence containers must depend on controlled types, and this is relatively heavy
+machinery. The new bounded containers might help,  but then more of the storage
+management burden is on the programmer.   As usual, no free lunch.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Friday, March 6, 2009  1:02 PM
+
+Sure, I agree with that, but Randy was being much too absolute. I dislike it
+when programming language folks tell you "I have this great new
+feature/language, but to use it you must abandon using xxx", it's as though a
+hardware store tried to sell you a great new plumbing tool that would solve all
+your problems, and then tell you that if you buy it you must abandon all your
+other tools :-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, March 6, 2009  2:17 PM
+
+...
+> Not all the world is containers!
+
+Of course. I was speaking in terms of the current discussion. Franco made the
+claim that we need to "fix" anonymous access types because of issuing using
+access types in OOP programming. Now, I can't speak for everybody, but the next
+low-level code that I see that is written using OOP will be the first! So I
+don't think the initial claim holds much water - I still think high-level ADTs
+should be done with a minimum of access types, and using OOP means that you are
+building high-level ADTs.
+
+Later you said:
+> Sure, I agree with that, but Randy was being much too absolute. I
+> dislike it > when programming language folks tell you "I have this
+> great new feature/language,
+> but to use it you must abandon using xxx", it's as though a hardware
+> store tried
+> to sell you a great new plumbing tool that would solve all your
+> problems, and then tell you that if you buy it you must abandon all
+> your other tools
+:-)
+
+I'm sure that's true; qualifying a statement like that properly means it loses
+all impact (great sound bites aren't qualified!). I did except bodies from it
+(one hopes that most lower-level code is encapsulated). And I surely was not
+talking about low-level packages that aren't designed for reuse (I like to call
+them "sloppy" packages, or "just throwing code"); those whatever you need to do
+is what you need to do. And that surely includes access types.
+
+So don't abandon your access types, but do try to keep them tightly under
+control (limited to a single package, ideally).
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Saturday, March 7, 2009  10:11 AM
+
+>I realize that I hold a minority view here, and I would like to have a
+>better understanding of why. But no one seems able to come up with a
+>counter-argument to the above points, they just say "I disagree" and
+>stop the conversation. It's almost like everyone has given up on
+>allowing the client any flexibility in structuring programs. (I saw the
+>same sort of thing in the old MFC libraries, but I blamed that on
+>C-think. Perhaps it is something deeper?)
+
+I am strongly on Randy's side here. Many years ago I named Unchecked_Conversions
+in package specifications, Unchecked_Perversion.  The reason?  It means that
+throughout any program that uses the package, the two types mentioned in the
+Unchecked_Conversion are Siamese twins that can't be separated.
+
+The same thing happens when a package declares a visible access type. The
+package can't manage storage for the designated type, and users of the package
+can't either.  So unless the access type explicitly uses a garbage collected
+storage pool, storage for the type will be unmanaged.  I certainly think that
+Robert Dewar's model of exporting a private type which is actually an access
+type is a big improvement, but I think better is to make the exported type a
+tagged record or better yet unconstrained array type. Now the user of the
+package knows he is being at least a little sinful if he sequesters a pointer to
+an object of the private type by using an explicit or anonymous access type.  If
+users may need to beat on an object, provide a (child or nested) generic package
+that provides a cursor.  You can also provide a much lighter weight (from a
+programming, not implementation point of view) function that returns the current
+object.  That it can only be used as input to another function or procedure is
+an advantage not a limitation.  For example:
+
+package Foo_Service is
+
+  type Connection is limited private;
+  ...
+  procedure Open(...);
+  function Current return Connection;
+  ...
+  generic
+  ...
+  package Additional is
+      procedure Open(...);
+      procedure Close(...);
+      function Current return Connection;
+  end Additional;
+  ...
+private
+  pragma Inline(Current);
+end Foo_Service;
+
+Of course, any call to either version of Current for a closed (or not yet
+opened) service will raise some appropriately named error.  What if users need
+to manage multiple services, say Ethernet connections?  Then use the model of
+the Ada IO packages, The fact that in rev 0.1  type Connection is an access type
+can be changed later, and users of the package should not need to be aware of
+the implementation change.  Much, much more work if you export an access type in
+the prototype implementation.
+
+What if I want to generalize the service using tagged types?  Change type
+Connection to tagged limited private, and have specialized child types for
+Internet, USB, Fire Wire, and so on. (You might even export an iterator over all
+open services in some future version, but I find the need for that suspect.)
+
+Better still is to use the model of generic package instance as an ADT:
+
+generic
+...
+package Service is
+  ...
+  function Read return Packet;
+  procedure Send(...);
+  ...
+end Service;
+
+If necessary you can have a Controlled object declared in the package body to do
+finalization, but usually that is not necessary.  If a user of the abstraction
+wants to open a dozen different instances simultaneously, he does have to go to
+the effort of naming them differently.  (Or create different threads. ;-)  Much
+more usual is for a user to create an instance in a nested scope that gets
+called many times.  Sometimes the information needed to open an instance is not
+going to be available when the instance is created, and you will need to provide
+an explicit open procedure in the package.  Shrug.  I usually run into this when
+the service is actually reading from a database a row at a time. (Each generic
+instance is a new query.) It still seems nicer to me than having to provide an
+explicit cursor and a way to iterate using it.  And if a user just reads part of
+the data then exits?  Fine, exiting the scope that created the instance does all
+the cleanup necessary, and there is o chance of dangling pointers.
+
+If setting up and tearing down a service is costly, the exporter of the
+abstraction can cache opened (system) services and, for example, create a task
+that closes inactive channels after 5 seconds or some such.  When the
+abstraction implementor does this he knows how many threads still have a channel
+open--the user has no way to keep an unauthorized pointer to the data
+structures.  To go back to the database example though, you usually want to put
+opening the database in the parent package, not in the generics.
+
+As for generalization, you don't even need tagged types  Just add generic child
+packages to either the non-generic parent (best) or as generic children of the
+generic package.
+
+To get back to the initial topic, I usually find that when OO programmers are
+screaming that they need this or that, the problem is often that they have not
+learned how to use the full generality of packages and generic packages in Ada.
+I do know that when teaching Ada, this dynamic view of packages, especially
+nested instances is hard to teach people who learned to program in some other
+language first.  (Fortran is the worst, but C and C++ can be just as bad.)
+Creating a (generic) package instance to hold the results of a database query is
+literally a foreign language.  (Thinking back, nested generics, where it takes
+two successive generic instantiations to create the abstraction wanted, is
+probably the hardest to teach.  It always seems like you should be able to
+collapse the two instantiations into one, but sometimes you just can't.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, March 8, 2009  10:03 PM
+
+I don't find the argument convincing that "if we can't solve every problem that
+anyone can identify, then we shouldn't solve any of them."  Incremental progress
+is still progress.  To me there are priorities, and some things are badly
+broken, while other "problems" seem to be more a matter of personal aesthetics
+of philosophy.  So I would start with prioritization, and discourage statements
+involving "absolutes." Ada is a wide-spectrum language, and it is dangerous to
+generalize too much from one's own experience with the language to start
+imposing limitations and requirements on all other users of the language.
+
+Personally I think we should focus on the features added in Ada 2005, in
+particular stand-alone local variables of an anonymous access type, and
+functions that return an anonymous access type, because clearly there is very
+little code and there are very few programmers that have become dependent on
+these features.
+
+****************************************************************
+
+From: Brad Moore
+Sent: Sunday, March 9, 2009  11:30 PM
+
+> > The 'Ref proposal has the advantage of solving all of the above,
+> > with full compatibility.  In addition, it solves most (all?) of the
+> > nice-to-haves.  However, it leaves the language in an odd state --
+> > an Ada textbook could tell people to use 'Ref always, and by the
+> > way, there are two useless features (named and anonymous access
+> > types), which should be avoided.  Also kind of ugly.
+>
+> I very much disagree that named access types are useless, I find this
+> very very odd.
+
+It also seems worth mentioning named access types currently play a role with
+Annex E and Remote Access Types. Would the 'Ref proposal come into play with
+RACW types? Also, in a Remote_Types unit, currently if you don't want an access
+to be treated as a remote access type you need to use an anonymous access type.
+
+eg.
+
+package Ada.Containers.Doubly_Linked_Lists is
+   pragma Preelaborate;
+   pragma Remote_Types;
+
+...
+
+   procedure Query_Element
+     (Position : Cursor;
+      Process  : not null access procedure (Element : Element_Type));
+
+Would the 'Ref proposal still allow this usage of anonymous access types? I
+haven't read the proposal yet, nor do I recall having come across it, but I am
+still catching up in my email...
+
+****************************************************************
 
+From: Gary Dismukes
+Sent: Monday, March 9, 2009  1:35 PM
+
+> Would the 'Ref proposal still allow this usage of anonymous access
+> types?
+
+There may be some interaction there, but presumably a 'Ref type would be treated
+like a named access type in such a unit.
+
+> I haven't read the proposal yet, nor do I recall having come across
+> it, but I am still catching up in my email...
+
+See the first part of the !appendix section in AI05-00138.  Franco sent that out
+back in November, so you probably just missed or forgot about it.
+
 ****************************************************************
 
 From: Bob Duff
-Sent: Thursday, March 5, 2009  7:51 AM
+Sent: Monday, March 9, 2009  7:16 AM
+
+> I don't find the argument convincing that "if we can't solve every
+> problem that anyone can identify, then we shouldn't solve any of
+> them."
+
+You are misrepresenting my position.  Or exagerating for effect.  ;-)
+
+Here's my position:  There are a dozen or so problems with anon access types.
+Several of them are essential to fix, if anon access is to be useful.  The rest
+are merely "nice to have".  I am strongly opposed to doing anything, unless we
+fix ALL of the "essential" ones.  Contrary to what you said above, I do not
+insist that we fix the "nice to haves" -- but it would be nice.
+
+>...Incremental progress
+> is still progress.  To me there are priorities, and  some things are
+>badly broken, while other "problems"
+> seem to be more a matter of personal aesthetics of  philosophy.  So I
+>would start with prioritization,  and discourage statements involving
+>"absolutes."
+
+I disagree.  We can make a prioritized list, if you like, but I think we need to
+draw a line, and say "everything above this line needs to be fixed -- otherwise,
+we write off anon access as a failed attempt."
+
+I'm too lazy to repeat all the issues here, but I'll just give two examples:
+
+Above the line: Need to be able to "new" and free objects portably.
+
+Below the line: It would be nice to have a way to specify Storage_Pool for anon
+access types.  (The 'Ref proposal solves this, but I do not insist that we go
+with the 'Ref proposal purely for this nice-to-have feature.)
+
+> Ada is a wide-spectrum language, and it is dangerous to generalize too
+> much from one's own experience with the language to start imposing
+> limitations and requirements on all other users of the language.
+
+I'm not imposing limitations on anybody.  It's just that I haven't seen a single
+realistic example of this anon access feature.  Not for lack of trying, either.
+
+> Personally I think we should focus on the features added in Ada 2005,
+> in particular stand-alone local variables of an anonymous access type,
+> and functions that return an anonymous access type, because clearly
+> there is very little code and there are very few programmers that have
+> become dependent on these features.
+
+We can, of course, argue about which problems need to be fixed.  But so far, you
+have refused to engage in that argument.  Sorry, but fixing stand-alone locals
+and returns is not enough, in my opinion.
+
+Sorry to be so strident on this issue, but we made the mistake once before: Ada
+95 had some problems with access types.  We designed an extremely complicated
+set of features to fix those problems.  Unfortunately, we failed to solve the
+problems sufficiently.  End result: huge implementation burden, but zero benefit
+to users.
 
+The reason I'm figuratively "pounding my shoe on the table" is I desperately
+want to avoid repeating that mistake.  Please don't take it personally!
+
 ****************************************************************
+
 From: Bob Duff
-Sent: Thursday, March 5, 2009  7:51 AM
+Sent: Monday, March 9, 2009  7:17 AM
 
+> I don't find the argument convincing that "if we can't solve every
+> problem that anyone can identify, then we shouldn't solve any of
+> them."
+
+Let me try an analogy:
+
+You have a vegetable garden.  The problem is, rabbits eat the vegetables before
+you can harvest them.  So let's put up a fence.
+
+We NEED a 4-sided fence that surrounds the whole garden.  A 3-sided fence is no
+good.  It costs a lot of effort to put up a 3-sided fence, but it doesn't solve
+the problem.  If you can't afford a complete solution, you might as well forget
+about it, and let the rabbits eat your food.  It's silly to talk about
+priorities for the North, South, East and West sides -- priority = "essential"
+for all.
+
+Do you see where I'm coming from?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, March 9, 2009  2:25 PM
+
+I don't really get the analogy, perhaps because I don't feel the
+"essential"-ness of some of the things you do.  I found the Ada 95 situation
+where anonymous access types were only used for parameters and discriminants was
+reasonable, as those are two places where you actually care about by-value vs.
+by-reference semantics, and where you want to be able to point to local objects
+safely.
+
+The main problem we were trying to solve for Ada 2005, in my mind, was to
+reduce, at least to some extent, the number of explicit conversions associated
+with typical OO paradigms.  I think others decided that it was important to go
+"all the way" and enable the elimination of all use of named access types. We
+seemed to run into trouble in getting the accessibility rules right when we
+started dealing with local variables and function results with anonymous access
+types.  I think we can fix those. And I don't see why we should leave them
+broken, even if there are other problems we don't know how to fix cleanly.
+
 ****************************************************************
+
 From: Bob Duff
-Sent: Thursday, March 5, 2009  7:51 AM
+Sent: Monday, March 9, 2009  1:44 PM
+
+> It also seems worth mentioning named access types currently play a
+> role with Annex E and Remote Access Types. Would the 'Ref proposal
+> come into play with RACW types?
+
+I don't know how 'Ref should interact with Annex E.  I haven't thought about it
+(and I don't intend to, unless we decide to move forward in that direction).
+
+>...Also, in a Remote_Types unit, currently if you  don't want an access
+>to be treated as a remote access type you need to  use an anonymous
+>access type.
+>
+> eg.
+>
+> package Ada.Containers.Doubly_Linked_Lists is
+>    pragma Preelaborate;
+>    pragma Remote_Types;
+>
+> ...
+>
+>    procedure Query_Element
+>      (Position : Cursor;
+>       Process  : not null access procedure (Element : Element_Type));
+>
+> Would the 'Ref proposal still allow this usage of anonymous access
+> types?
+
+You're referring to Process?
+
+First, the 'Ref proposal would not disallow any anonymous access types currently
+allowed, nor change their semantics.  The whole point of 'Ref is to leave anon
+access alone, for compatibility, which makes us free to use different rules for
+'Ref.
+
+Second, 'Ref is not intended to address access-to-subprogram, only
+access-to-object.  We could discuss changing that in some way, but it seems
+premature at this point.
+
+> I haven't read the proposal yet, nor do I recall having come across
+> it, but I am still catching up in my email...
+
+It is discussed in AI05-0138-1.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 9, 2009  3:26 PM
+
+> Sorry to be so strident on this issue, but we made the mistake once
+> before:
+> Ada 95 had some problems with access types.  We designed an extremely
+> complicated set of features to fix those problems.
+> Unfortunately, we failed to solve the problems sufficiently.
+> End result: huge implementation burden, but zero benefit to users.
+>
+> The reason I'm figuratively "pounding my shoe on the table"
+> is I desperately want to avoid repeating that mistake.
+> Please don't take it personally!
+
+I strongly agree with Bob here. We need to focus on the problems (and by
+problems, I mean the *high-level* problems designing Ada programs, ADT, etc.).
+If those problems need anonymous access types to be solved, then we will know
+what to work on. If not, then we surely should not waste the effort on them.
+
+This is very much an issue of throwing good money after bad (sort of like
+investing in the stock market these days!!) Anonymous access types look like a
+mistake in the language to me, and they'll probably remain a mistake no matter
+how much effort is put into them. We'll need to do some fixes to make the
+semantics correct, but beyond that I need to be convinced that they actually
+solve some problem.
+
+After all, the expansion of anonymous access types in Ada 2005 was supposed to
+cut down on unnecessary type conversions for programs involving limited with.
+But they don't do that unless you get rid of all named access types from your
+program. But that was never, ever, the intent (which is why there is no way to
+do [sane] allocation or [any] deallocation of them). That makes the expansion a
+complete failure; and the only reasonable fix would be to get rid of the
+requirement for explicit conversions *from* anonymous access types to named
+access types. If we don't do that, other changes are just lipstick on a pig.
+(And I'm strongly opposed to trying to get storage pools on anonymous access
+types!).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, March 9, 2009  3:43 PM
+
+> You are misrepresenting my position.  Or exaggerating for effect.  ;-)
+>
+> Here's my position:  There are a dozen or so problems with anon access types.
+> Several of them are essential to fix, if anon access is to be useful.
+> The rest are merely "nice to have".  I am strongly opposed to doing
+> anything, unless we fix ALL of the "essential" ones.  Contrary to what
+> you said above, I do not insist that we fix the "nice to haves" -- but it would be nice.
+
+When I look back at your original note on this topic, you identify a handful of
+problems, and then list a series of changes that you feel are required.  You may
+have felt that the solutions implied the problems they were fixing, but not
+everyone can make that leap.
+
+It might be helpful for us to first only identify and prioritize the problems,
+and try to avoid slipping into prematurely specifying solutions. You indicate
+you think there are a dozen or so such problems, but that only some of them are
+essential to fix.  Let's see if we can get a cohesive list of what are the real
+problems.
+
+I believe Franco's notes suffered from the same issue.
+That is, he identified a few problems, and then immediately launched into a
+rather elaborate set of solutions.  I personally believe we could solve almost
+all of the problems Franco identified, with a significantly simpler set of
+solutions. But my fear is that it is easy to fall in love with a particular
+solution, and then become blinded to what are the real problems, and anything
+that doesn't match the envisioned solution, even if it happens to solve pretty
+much the same problems, will be discounted.
+
+ From Franco's note on 'Ref, I extracted the following problems:
+
+    * Can't use unchecked deallocation
+
+    * Can't specify storage pool or storage size
+
+    * Can't have [in] out access parameters
+
+    * Can't use them with task entries
+
+    * Can't reverse a list represented using anonymous
+      access type pointers (underlying problem -- accessibility
+      level of local variables of an anonymous access type).
+
+    * Equality operator is ambiguous with anonymous access types.
+      But I'm not sure the example given is correct:
+       declare
+         X : access T := ...;
+         Y : aliased T := ...;
+       begin
+         if X = Y'Access then ... -- Ambiguous?
+
+      The only "=" operator I can imagine being used for this
+      is the unique one in package Standard for univ-access.
+      Is there some other one that is getting in the way?
+      There is no implicit conversion *from* an anonymous
+      access type.
+
+ From the note about allocators, I extracted the following problems:
+
+    * anonymous-type allocators are generally short-lived, while named-type
+      allocators have a lifetime determined by their type.
+
+ From the second note about allocators, the problems seem to be the same ones
+ identified earlier, namely a lack of unchecked deallocation, and ability to
+ specify storage pool or storage size.
+
+I'd be curious of the above problems identified by Franco, which ones make it
+onto the "essential to solve" list for some of us.  For me, if you want control
+over storage, then by definition you will want the fine level of control
+provided by named access types.  You can still use anonymous access types for
+manipulating values, but you need to use a named access type when allocating and
+freeing if you want user-specified storage pools.  It seems very limiting to
+presume that all users of access types with the same designated type would have
+the same storage-management requirements.
+
+Task entries seems pretty low on the totem pole.
+
+I'm not sure there really is a problem with the equality operator.
+
+The reversing-a-list example was pretty compelling to me, but I believe that can
+be solved relatively simply.
+
+I had more trouble extracting Bob's problem list.  Here is my attempt.
+Corrections/refinements appreciated.
+
+   * Dynamic accessibility is too confusing;
+
+   * Automatic deallocation is undesirable for objects
+     created by anonymous allocators;
+
+   * IN OUT access parameters are needed;
+
+   * IN OUT function parameters are needed.
+
+Hopefully we could identify at least a few problems we all think are "essential"
+to solve, before we start debating specific solutions.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 9, 2009  5:03 PM
+
+...
+> It might be helpful for us to first only identify and prioritize the
+> problems, and try to avoid slipping into prematurely specifying
+> solutions. You indicate you think there are a dozen or so such
+> problems, but that only some of them are essential to fix.  Let's see
+> if we can get a cohesive list of what are the real problems.
+
+This makes sense to me.
+
+> I believe Franco's notes suffered from the same issue.
+
+Even worse, he didn't clarify the issues when asked (at least the ones I asked
+about).
+
+...
+> I'd be curious of the above problems identified by Franco, which ones
+> make it onto the "essential to solve" list for some of us.  For me, if
+> you want control over storage, then by definition you will want the
+> fine level of control provided by named access types.  You can still
+> use anonymous access types for manipulating values, but you need to
+> use a named access type when allocating and freeing if you want
+> user-specified storage pools.  It seems very limiting to presume that
+> all users of access types with the same designated type would have the
+> same storage-management requirements.
+
+I agree with this, but note that means that allocators of anonymous access types
+are probably a mistake.
+
+...
+> I had more trouble extracting Bob's problem list.  Here is my attempt.
+> Corrections/refinements appreciated.
+>
+>    * Dynamic accessibility is too confusing;
+>
+>    * Automatic deallocation is undesirable for objects
+>      created by anonymous allocators;
+>
+>    * IN OUT access parameters are needed;
+>
+>    * IN OUT function parameters are needed.
+>
+> Hopefully we could identify at least a few problems we all think are
+> "essential" to solve, before we start debating specific solutions.
+
+You didn't even try to extract mine, even though I've written a whole bunch of
+proposals on various topics. I'm starting to feel neglected. :-)
+
+Anyway, trying the same form as you did for Bob:
+
+Randy's problem list (in rough order of necessity):
+
+    * In Out parameters for functions;
+
+      [I don't think this one falls into this particular category, although I
+      understand that having it decreases the need to use anonynous access
+      types, and thus reduces the priority of other fixes.]
+
+    * Safe accessors for containers;
+
+      [That is, the ability to return an access to part of a parameter of a function, and have it have an appropriate (very-short) lifetime so that only a dereference is a possibility. But there are other possibilities as well for this, such as a general 
return-by-reference issue.]
+
+    * Storage pools need the possibility of detecting dangling pointers;
+
+      [GNAT has a solution for that.]
+
+    * Restriction/other setting to prohibit allocators for anonymous access
+      types (assuming we follow Tucker's allocate with named access only
+      strategy);
+
+      [Compatibility issues prevent us from making this a requirement, even
+      though that would be best.]
+
+All of the above have practical use-cases that make them important.
+
+    -- Nice-to-haves:
+
+    * Decouple accessibility from location of declaration for access types;
+
+    * Mechanism of testing accessibility of an access value so that dynamic
+      accessibility failures can be prevented/handled;
+
+    * Decouple "access values" from System.Address in Storage_Pools;
+
+    * Actually solve the problem of too many type conversions for access to
+      limited views.
+
+      [I suspect this is what Franco's problems *really* boil down to. I'm
+       personally dubious of the need for visible accesses in the first place,
+       but I don't want to dismiss anything out of hand.]
 
+More food for thought.
+
+BTW, what's your personal list, Tucker??
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, March 9, 2009  5:40 PM
+
+I didn't mean to neglect you.  I just didn't find a separate recent proposal
+from you, so it wasn't as easy to find your list.
+
+For my list, I think the two things that are currently "broken" are 1) the
+accessibility rules related to standalone objects of an anonymous access (as
+illustrated by Franco's reversal use, but also because a constant initialized
+from an access parameter and a renaming of an access parameter produce such
+different results), and 2) the accessibility rules related to anonymous access
+return (as illustrated by the problems with dispatching operations, and by the
+inevitable storage leaks mentioned in AI-51).
+
+I am quite used to having separate access types for allocation/deallocation and
+for manipulation, because the code for manipulating in general doesn't need to
+worry about storage management, and so can be largely storage-pool independent.
+So for me, if the type for manipulation ends up anonymous because that works
+more naturally, while the type(s) for allocation/deallocation remain named,
+that's just fine.
+
+I think it is unfortunate that you only get one global storage pool for a named
+access type, and AI-111 is an attempt to address that problem, but it is largely
+independent of the current discussion about anonymous access types (though not
+completely).
+
 ****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 9, 2009  6:06 PM
+
+> I didn't mean to neglect you.  I just didn't find a separate recent
+> proposal from you, so it wasn't as easy to find your list.
+
+Did you ever read the proposals that I sent that are in the !appendix of
+AI05-0138-1 (specifying accessibility), the storage pool proposal now in
+AI05-0141-1, and the accessor problem in AI05-0142-1? The latter two aren't
+directly associated with anonymous access types, but one could use anonymous
+access types as an alternative solution to AI05-0142-1's problem (so they're
+related in that way). Not to mention AI05-0143-1 ("in out parameters for
+functions") and the partially written AI05-0144-1 ("detecting order
+dependencies"), both of which use your name in vain (as you are the most visible
+opponent).
+
+Admittedly, all of these are a month old or so, but until Bob started sending
+notes, they covered pretty much everything. (And I don't think anything that Bob
+or you have said has changed my opinions much to date.) It's would be nice if
+you've read them before we have the conference call (I know Bob has). I wish I
+had time to finish these other proposals before then, but that seems unlikely.
+
+****************************************************************
+
 From: Bob Duff
-Sent: Thursday, March 5, 2009  7:51 AM
+Sent: Tuesday, March 10, 2009  5:57 PM
+
+I can't find the e-mail I want to reply to right now, but I want to make this
+point:
 
+Tuck said that the Ada 95 anon access features work pretty well.
+
+Well, I partly agree: access parameters and access discriminants work pretty
+well as special-purpose gizmos, with various special purpose rules.  One can
+memorize the rules, and deal with it.
+
+But Ada 2005 adds anon access all over, and makes it seem like a general purpose
+feature, and that makes the special purpose rules far more confusing.
+
 ****************************************************************
+
 From: Bob Duff
-Sent: Thursday, March 5, 2009  7:51 AM
+Sent: Tuesday, March 10, 2009  5:51 PM
+
+> It might be helpful for us to first only identify and prioritize the
+> problems, and try to avoid slipping into prematurely specifying
+> solutions. You indicate you think there are a dozen or so such
+> problems, but that only some of them are essential to fix.  Let's see
+> if we can get a cohesive list of what are the real problems.
+
+OK, you've made a good list of issues based on Franco's and my e-mails, below. I
+replied "Above the line." to each issue below, to indicate that it really has to
+be fixed, or "Below the line." to indicate that it's merely nice to have. I
+think there are some missing "below" issues, but you've got the "above" ones,
+which is the important thing.
+
+I'm imagining a "line" drawn across a prioritized listing, highest prio first.
+
+First let me mention some "meta issues", which are really covered by the issues
+you list below, but may serve as rationale for where to draw the "line".
+
+Whenever I declare a type T, I have to decide whether to put "type Access_T is
+access all T" (or maybe T'Class) immediately after, just in case it's needed. If
+yes, I clutter the program with useless access types.  If no, then I have to
+create named access types on an as-needed basis, scattered about, and this
+exacerbates the "bogus type conversion" issue.  Or else I have to go back and
+modify existing code, which can range from "minor annoyance" to "impossible". I
+don't like that dilemma.  This explains my point below about 'out' parameters --
+I don't like a coding rule that says, "Declare Access_T if and only if you need
+to have 'out' parameters somewhere else".
+
+If I have to have Access_T anyway, then "X: access T" is not a big win over "X:
+Access_T".  Unless of course it eliminates bogus conversions.  In my experience,
+they aren't eliminated, but moved around.  And it's confusing.
+
+Another meta issue is just general complexity.  I can't point to one particular
+"problem" that causes the complexity, but taken together, all the anon access
+rules feel too complicated.
+
+In the end, we need some realistic examples using anon access, that somehow are
+"better" than using named access (e.g. by removing bogus conversions, while
+remaining "simple" for the typical programmer).  If we can't do that, then it's
+a waste of time to "fix" anon access.
+
+[End meta issues.]
+
+> I believe Franco's notes suffered from the same issue.
+
+I am guilty as accused (sorry), but Franco, not so much.
+He did list "problems" separately from "solutions".
+
+> That is, he identified a few problems, and then immediately launched
+> into a rather elaborate set of solutions.  I personally believe we
+> could solve almost all of the problems Franco identified, with a
+> significantly simpler set of solutions.
+> But my fear is that it is easy to fall in love with a particular
+> solution, and then become blinded to what are the real problems, and
+> anything that doesn't match the envisioned solution, even if it
+> happens to solve pretty much the same problems, will be discounted.
+>
+>  From Franco's note on 'Ref, I extracted the following problems:
+>
+>     * Can't use unchecked deallocation
+
+Above the line.
+
+>     * Can't specify storage pool or storage size
+
+Below the line.
+
+>     * Can't have [in] out access parameters
+
+Above the line.
+
+>     * Can't use them with task entries
+
+Below the line.  This is really the same issue as the previous "[in] out" one,
+but entries are much more rare than [in] out params (and will be more so once we
+allow [in] out params on functions ;-)).
+
+>     * Can't reverse a list represented using anonymous
+>       access type pointers (underlying problem -- accessibility
+>       level of local variables of an anonymous access type).
+
+Above the line.
+
+>     * Equality operator is ambiguous with anonymous access types.
+>       But I'm not sure the example given is correct:
+>        declare
+>          X : access T := ...;
+>          Y : aliased T := ...;
+>        begin
+>          if X = Y'Access then ... -- Ambiguous?
+>
+>       The only "=" operator I can imagine being used for this
+>       is the unique one in package Standard for univ-access.
+>       Is there some other one that is getting in the way?
+
+I don't remember the details of this issue.  It might be above the line.
+
+>       There is no implicit conversion *from* an anonymous
+>       access type.
+
+I've always wondered why that is.  Some obscure incompatibility issue involving
+overload resolution, I suppose.
+
+>  From the note about allocators, I extracted the following problems:
+>
+>     * anonymous-type allocators are generally short-lived, while named-type
+>       allocators have a lifetime determined by their type.
+
+Above the line.
+
+>  From the second note about allocators, the problems seem to be the
+> same ones identified earlier, namely a lack of unchecked deallocation,
+> and ability to specify storage pool or storage size.
+>
+> I'd be curious of the above problems identified by Franco, which ones
+> make it onto the "essential to solve" list for some of us.  For me, if
+> you want control over storage, then by definition you will want the
+> fine level of control provided by named access types.  You can still
+> use anonymous access types for manipulating values, but you need to
+> use a named access type when allocating and freeing if you want
+> user-specified storage pools.  It seems very limiting to presume that
+> all users of access types with the same designated type would have the
+> same storage-management requirements.
+>
+> Task entries seems pretty low on the totem pole.
+
+Agreed.
+
+> I'm not sure there really is a problem with the equality operator.
+
+I'm not sure.
+
+> The reversing-a-list example was pretty compelling to me, but I
+> believe that can be solved relatively simply.
+>
+> I had more trouble extracting Bob's problem list.  Here is my attempt.
+> Corrections/refinements appreciated.
+
+Sorry for causing confusion.  Anyway, I think you got it.  Not surprisingly, all
+of these are above the line, since in the message you're referring to, I
+deliberately left out the ones that Franco and I had decided were mere "nice to
+haves".
+
+>    * Dynamic accessibility is too confusing;
+
+Above the line.  Not just confusing, but it breaks abstraction. I'd actually
+broaden this: Accessibility level of any anon access type is confusing, unless
+it matches the accessibility level of a named access type.  And I don't mean a
+named type declared in some weird place, I mean a named type declared where a
+normal programmer would put it -- immediately after the declaration of type T.
+Coextensions are a cool feature, but they are deeply confusing, so I doubt most
+programmers can make use of them.
+
+>    * Automatic deallocation is undesirable for objects
+>      created by anonymous allocators;
+
+Above the line.  Basically this is the same issue as "* Can't use unchecked
+deallocation" under Franco's list.
+
+>    * IN OUT access parameters are needed;
+
+Above the line.
+
+>    * IN OUT function parameters are needed.
+
+Above the line.  But maybe this is a "meta issue".  The primary reason to pass
+Local'Access to an anon access parameter is because you wanted 'in out', but you
+weren't allowed, because it's a function.  In other words, allowing 'in out'
+params on functions gives us freedom elsewhere in the language design.
+
+> Hopefully we could identify at least a few problems we all think are
+> "essential" to solve, before we start debating specific solutions.
+
+OK.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 11, 2009  7:57 AM
+
+Note that "in out" access parameters are not trivial, because with "in"
+parameters you can generally use static approximations of the true dynamic
+accessibility level, but with "out" parameters you might open yourself up to
+dangling references if you make certain approximations. I don't have a ready
+example to show the problem, but I could probably come up with one if given
+enough time. I believe this was one of the reasons we didn't allow OUT access
+parameters.
+
+I might also add that the number of times I have seen an OUT parameter of a
+named access type is pretty small, so I don't feel the same critical need for
+OUT parameters of an anonymous access type, especially if they make the
+accessibility rules for access parameters even more complex.  Note that
+languages like Java don't have any OUT parameters of a pointer type, and somehow
+manage to muddle through.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 11, 2009  9:22 PM
+
+[To Randy] Thanks for the pointer to these AIs.  An immediate reaction to the
+accessibility specification suggestion -- the proposed general syntax for
+specifying aspects might help here:
+
+    X : access T
+      with
+        Accessibility => System.Library_Level;
+
+(presuming we add an appropriate enumeration type to package System)
+
+I'll make sure I review all of your proposals before the phone call.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 11, 2009  1:18 PM
+
+> Note that "in out" access parameters are not trivial,
+
+They would be trivial if accessibility level of all anon access types is static,
+and is that of the designated subtype.  (Or maybe the root type of hierarchy,
+for tagged.)
+
+I realize that's incompatible with Ada 95.  We've got two suggestions to avoid
+compatility problems, 'Ref, and pragma Static_Accessibility, both of which seem
+to be rejected by most people so far.  So we seem kind of stuck...
+
+> I don't have a ready example to show the problem, but I could probably
+> come up with one if given enough time.
+
+Oh, I believe that!
+
+> I might also add that the number of times I have seen an OUT parameter
+> of a named access type is pretty small, so I don't feel the same
+> critical need for OUT parameters of an anonymous access type, ...
+
+OK, I'm half convinced.  Only half.  It really seems an annoying non-uniformity,
+and gets you into the dilemma I mentioned.
+
+>...especially if they make
+> the accessibility rules for access parameters even more  complex.
+>Note that languages like Java don't have any  OUT parameters of a
+>pointer type, and somehow manage  to muddle through.
+
+That's not my favorite "feature" of Java, FWIW.
+
+Speaking of Java, it manages to muddle through without any accessibility rules,
+using a technology I won't name, but whose initials are GC.  ;-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 11, 2009  3:21 PM
+
+I'm not personally interested in reinventing Ada 95's anonymous-access-type
+rules.  I think we can fix some of the mistakes we made in the Ada 2005
+additions.  I could also imagine some new pragma-restriction identifiers
+associated with anonymous access types, such as No_Anonymous_Allocators.  But
+starting with a completely different model for anonymous access types is not
+good for the language, in my view.
+
+I think IN OUT access parameters could work if they are essentially fully
+dynamic, with a dynamic accessibility check on copy-out.  This pretty much means
+implementations would have to abandon using static accessibility levels for
+access parameters, and instead pass a pointer to something like a "master"
+record, which indicates the lifetime of the designated object.
+
+The master record/storage pool might have a static nesting level stored which
+could be used in many cases, as well as a dynamic nesting level, and presumably
+a pointer to the immediately enclosing master record.
+
+Note that this is the direction that AI-111 was heading to support "subpools".
+
+FWIW, overall, I am tending toward the following model:
+
+   - stand-alone objects/parameters of an anonymous
+     access type are fully dynamic (membership can
+     be used for checking before converting to a
+     named type);
+
+   - access results (of a function) take their (dynamic)
+     accessibility from the caller context (per AI-51);
+
+   - discriminants work as they do in Ada 95,
+     where accessibility is determined by the enclosing
+     object.
+
+(The first two are what I would call "chameleon" semantics,
+  where the object takes on the accessibility of its
+  current value or context.)
+
+The open question, at least for me, is whether our model for non-discriminant
+components is right, where they have the accessibility of the enclosing
+composite *type*.  Other alternatives are to make them fully dynamic, or to make
+them like discriminants, where they take their accessibility from the enclosing
+*object*, or to allow some kind of accessibility/storage-pool specification,
+similar to what Randy has proposed.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  3:39 PM
+
+> > Note that "in out" access parameters are not trivial,
+>
+> They would be trivial if accessibility level of all anon access types
+> is static, and is that of the designated subtype.  (Or maybe the root
+> type of hierarchy, for tagged.)
+>
+> I realize that's incompatible with Ada 95.  We've got two suggestions
+> to avoid compatility problems, 'Ref, and pragma Static_Accessibility,
+> both of which seem to be rejected by most people so far.  So we seem
+> kind of stuck...
+
+Sheesh, I'm being ignored again! We have *three* suggestions for avoiding
+compatibility problems and still getting static accessibility on anonymous
+access types: 'Ref, pragma Static_Accessibility (which BTW, I never saw any
+proposal for other than a mention in passing -- where did this name come
+from???), and specifying accessibility (see the detailed proposal in AI05-0138's
+appendix). Of course, your conclusion still seems pretty much valid: no one
+seems excited by any of these ideas.
+
+> > I don't have a ready example to show the problem, but I could
+> > probably come up with one if given enough time.
+>
+> Oh, I believe that!
+>
+> > I might also add that the number of times I have seen an OUT
+> > parameter of a named access type is pretty small, so I don't feel
+> > the same critical need for OUT parameters of an anonymous access type, ...
+>
+> OK, I'm half convinced.  Only half.  It really seems an annoying
+> non-uniformity, and gets you into the dilemma I mentioned.
+
+I'm not sure I am. I would agree with Tucker's statement taken literally, but it
+ignores "in out" parameters, which are far more common than "out" parameters (at
+least in my code). I would guess that he is including "in out" parameters in it,
+and then I would disagree (although it may be true that many of those cases
+aren't really modifying the parameter.
+
+I could make a similar statement that is just as true:
+
+"I might also add that the number of times I have seen an anonymous access
+parameter that couldn't be better written as an "in out" or "out" parameter or
+as a parameter of a named access type is pretty small, so I don't feel the same
+critical need for other modes for parameters of an anonymous access type, ..."
+
+But I don't find this particularly compelling, either, because YMMV. If we're
+going to bother to have the things, they should be consistent as to how they are
+used.
+
+> >...especially if they make
+> > the accessibility rules for access parameters even more  complex.
+> >Note that languages like Java don't have any  OUT parameters of a
+> >pointer type, and somehow manage  to muddle through.
+>
+> That's not my favorite "feature" of Java, FWIW.
+>
+> Speaking of Java, it manages to muddle through without any
+> accessibility rules, using a technology I won't name, but whose
+> initials are GC.  ;-)
+
+Of course, they give up the benefits of stack allocation to get there.
+
+An alternative way for Ada to "muddle through" would be to make all
+accessibility dynamic (optionally, I think; that was the original idea behind my
+specified accessibility proposal); then the only accessibility failures would be
+when you are dereferencing a pointer that is actually dangling (or converting to
+a type with static accessibility). The problem with that is that I wasn't able
+to figure out a way to implement the accessibility check without a distributed
+overhead (simply checking the relationship of stack frames isn't enough, even
+within a single task). Maybe someone is cleverer than I on that.
+
+With fully dynamic accessibility checks, the only failures occur when there are
+real bugs. The main problem with static accessibility as we have it is that it
+prevents many things that are perfectly reasonable and that happens a lot more
+often than it detects actual bugs.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  3:55 PM
+
+...
+> The open question, at least for me, is whether our model for
+> non-discriminant components is right, where they have the
+> accessibility of the enclosing composite *type*.  Other alternatives
+> are to make them fully dynamic, or to make them like discriminants,
+> where they take their accessibility from the enclosing *object*, or to
+> allow some kind of accessibility/storage-pool specification, similar
+> to what Randy has proposed.
+
+Unfortunately, I've convinced that fully dynamic accessibility in general is not
+implementable without distributed overhead, because comparison of stack frames
+is not enough (even within a single task). Access parameters get away with it
+because the stack relationship is not fully general due to the relationship
+implied by calls. (There is also the issue of incomparable accessibility, but I
+think that a check could be engineered to minimize that overhead, as the number
+of checks between two different tasks is likely to be very low).
+
+I could show the problem on a whiteboard in 30 seconds, but I don't know of a
+good way to describe it in text.
+
+I'm concerned that the problem could show up in anonymous access objects,
+although I think that would depend on how dynamic the results of functions
+really are and how dynamic the accessibility is (if it is only dynamic when
+initialized I think we are OK).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  4:08 PM
+
+...
+> I'm concerned that the problem could show up in anonymous access
+> objects, although I think that would depend on how dynamic the results
+> of functions really are and how dynamic the accessibility is (if it is
+> only dynamic when initialized I think we are OK).
+
+Here's a case that worries me for "stand-alone objects/parameters of an
+anonymous access type are fully dynamic (membership can be used for checking
+before converting to a named type)":
+
+    declare
+        Obj : access Integer;
+
+        procedure Do_It (Value : in Integer) is
+            Local : aliased Integer := Value;
+        begin
+            if Value mod 3 = 0 then
+                Obj := Local'Access; -- (1)
+            else
+                Obj.All := Value + Obj.All; -- (2)
+            end if;
+        end Do_It;
+    begin
+        Do_It (3);
+        Do_It (4);
+    end;
+
+The first call to Do_It saves an access to an object; as the object is has fully
+dynamic accessibility, this is OK. The second call to Do_It uses the object
+saved by the first call at (2) -- but it no longer exists. So (a) there is a
+requirement to make accessibility checks on dereferences, and (b) a master stack
+address comparision doesn't work (they're both the same in this case, which
+normally should pass the check).
+
+You could fix this case by including a master serial number with each one (in
+this case, the frames are the same but the serial number is not). But if Do_It
+was a recursive routine much a like a fibinacci routine, that check plus a stack
+address check would not be enough. You would have to walk from the current
+master to see if one with the correct address and serial number appeared. On
+*every* dereference (and conversion). Plus the distributed overhead of the
+serial number. That all seems too much to me (if I thought that was reasonable,
+I would have proposed a fully dynamic modifier for all access type
+declarations).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 11, 2009  4:30 PM
+
+...
+>     declare
+>         Obj : access Integer;
+>
+>         procedure Do_It (Value : in Integer) is
+>             Local : aliased Integer := Value;
+>         begin
+>             if Value mod 3 = 0 then
+>                 Obj := Local'Access; -- (1)
+
+This would be statically illegal.  In the "fully dynamic" model I have suggested
+in the past for stand-alone variables, it is still that case that an access
+object would never be allowed to point to an object that has a shorter lifetime
+than the access object.
+
+>             else
+>                 Obj.All := Value + Obj.All; -- (2)
+
+This would not require a dynamic check if you disallow access objects pointing
+to things shorter-lived than themselves.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  4:55 PM
+
+> This would be statically illegal.  In the "fully dynamic"
+> model I have suggested in the past for stand-alone variables, it is
+> still that case that an access object would never be allowed to point
+> to an object that has a shorter lifetime than the access object.
+
+OK, but that's not by any stretch of the imagination a "fully dynamic" model.
+That's a mixed static/dynamic model, because you clearly have to have some
+static checks to enforce "shorter lifetime" rule. (Why the heck didn't we call
+this "lifetime" in the first place? People would understand it better. And yes,
+I made that suggestion way back in the Ada 9X days, but even then you were too
+entrenched with the awful terminology of "accessibility" to consider the
+change.)
+
+I don't recall you ever describing in any sort of detail what this model is, and
+I think you need to do that so we can evaluate it fairly. (You have a track
+record of morphing accessibility rules to whatever will get approval by the ARG,
+and then later discovering problems that make it necessary to adopt the overly
+complex rules you originally had in mind. That probably wasn't intentional, but
+still it implies insufficient detail or understanding or something. I for one do
+not want to get fooled again in this regard, I will oppose all accessibility
+changes unless the model is clearly laid out and vetted, especially as
+accessibility is a nearly worthless set of checks that simply has to be worked
+around - and even the Ada 9x designers recognized that by including a
+first-class way to get around the checking - 'Unchecked_Access.)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 11, 2009  4:33 PM
+
+> Here's a case that worries me for "stand-alone objects/parameters of
+> an anonymous access type are fully dynamic (membership can be used for
+> checking before converting to a named type)":
+
+Hmm.  I never thought "fully dynamic" was THAT dynamic!  I thought it meant that
+you'd get an exception at (1) below.
+
+But even my not-so-fully dynamic notion has problems with tasks.
+
+>     declare
+>         Obj : access Integer;
+>
+>         procedure Do_It (Value : in Integer) is
+>             Local : aliased Integer := Value;
+>         begin
+>             if Value mod 3 = 0 then
+>                 Obj := Local'Access; -- (1)
+>             else
+>                 Obj.All := Value + Obj.All; -- (2)
+>             end if;
+>         end Do_It;
+>     begin
+>         Do_It (3);
+>         Do_It (4);
+>     end;
+>
+> The first call to Do_It saves an access to an object; as the object is
+> has fully dynamic accessibility, this is OK. The second call to Do_It
+> uses the object saved by the first call at (2) -- but it no longer
+> exists. So (a) there is a requirement to make accessibility checks on
+> dereferences, and (b) a master stack address comparision doesn't work
+> (they're both the same in this case, which normally should pass the check).
+>
+> You could fix this case by including a master serial number with each
+> one (in this case, the frames are the same but the serial number is
+> not). But if Do_It was a recursive routine much a like a fibinacci
+> routine, that check plus a stack address check would not be enough.
+> You would have to walk from the current master to see if one with the
+> correct address and serial number appeared. On *every* dereference
+> (and conversion). Plus the distributed overhead of the serial number.
+> That all seems too much to me (if I thought that was reasonable, I
+> would have proposed a fully dynamic modifier for all access type declarations).
+
+I agree the implementation model here is just nuts.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 11, 2009  4:44 PM
+
+> > I realize that's incompatible with Ada 95.  We've got two
+> > suggestions to avoid compatility problems, 'Ref, and pragma
+> > Static_Accessibility, both of which seem to be rejected by most
+> > people so far.  So we seem kind of stuck...
+>
+> Sheesh, I'm being ignored again!
+
+Sorry!
+
+>...We have *three* suggestions for avoiding  compatibility problems and
+>still getting static accessibility on anonymous  access types: 'Ref,
+>pragma Static_Accessibility (which BTW, I never saw any  proposal for
+>other than a mention in passing -- where did this name come  from???),
+
+I think Franco invented it, more-or-less on the fly.  There's no actual
+"proposal", just the idea that we want to change the rules, and that's
+incompatible, so we invent a pragma or some other sort of option, which invokes
+the rules we like, and then programs without that pragma can function as in Ada
+95/2005.
+
+>... and specifying accessibility (see the detailed proposal in
+>AI05-0138's appendix).
+
+Yes, I remember that one.  I don't much like any idea that requires some extra
+verbiage on every type.  If you can come up with a global way to say it, then
+I'd be happier.  (And the string-literal-based syntax is pretty horrible, IMHO,
+but that's a detail.)
+
+>...Of course, your conclusion still seems pretty much
+> valid: no one seems excited by any of these ideas.
+...
+
+> I'm not sure I am. I would agree with Tucker's statement taken
+> literally, but it ignores "in out" parameters, which are far more common than "out"
+> parameters (at least in my code). I would guess that he is including
+> "in out" parameters in it, and then I would disagree (although it may
+> be true that many of those cases aren't really modifying the parameter.
+>
+> I could make a similar statement that is just as true:
+>
+> "I might also add that the number of times I have seen an anonymous
+> access parameter that couldn't be better written as an "in out" or
+> "out" parameter or as a parameter of a named access type is pretty
+> small, so I don't feel the same critical need for other modes for
+> parameters of an anonymous access type, ..."
+
+Right, except that 'in out' is disallowed for functions.
+
+> But I don't find this particularly compelling, either, because YMMV.
+> If we're going to bother to have the things, they should be consistent
+> as to how they are used.
+>
+> > >...especially if they make
+> > > the accessibility rules for access parameters even more  complex.
+> > >Note that languages like Java don't have any  OUT parameters of a
+> > >pointer type, and somehow manage  to muddle through.
+> >
+> > That's not my favorite "feature" of Java, FWIW.
+> >
+> > Speaking of Java, it manages to muddle through without any
+> > accessibility rules, using a technology I won't name, but whose
+> > initials are GC.  ;-)
+>
+> Of course, they give up the benefits of stack allocation to get there.
+
+Right.  Java makes the mistake of saying "now that we have GC, we might as well
+put everything on the heap".  But it doesn't have to be that way -- e.g. C#
+doesn't make that mistake.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  5:08 PM
+
+...
+> > Here's a case that worries me for "stand-alone objects/parameters of
+> > an anonymous access type are fully dynamic (membership can be used
+> > for checking before converting to a named type)":
+>
+> Hmm.  I never thought "fully dynamic" was THAT dynamic!  I thought it
+> meant that you'd get an exception at (1) below.
+
+So you had a different idea of what Tucker was proposing than me or Tucker:
+three people, three different ideas of what was being proposed. This is not
+good! Tucker needs to write a much more detailed proposal, so we can at least
+discuss a single idea...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 11, 2009  5:13 PM
+
+> I don't recall you ever describing in any sort of detail what this
+> model is, and I think you need to do that so we can evaluate it fairly. ...
+
+Here is a paragraph from an e-mail I sent on 11/12/2008:
+
+   One point to add, the dynamic accessibility level should never
+   be allowed to become *deeper* than that of the access object itself,
+   or you have a sure recipe for a dangling reference.  That
+   is, even if we were to make the accessibility level dynamic,
+   it would be limited to that of the access object.  It could
+   only be the same as or shallower than that.  Hence you would
+   still get a compile-time error if you tried to assign the
+   'Access of a nested aliased object via an up-level reference to
+   an enclosing stand-alone access object.  This means that
+   library-level access objects are not a special case, since
+   there is nothing "shallower" than library-level, meaning that
+   the "dynamic" accessibility level can never be anything by
+   library-level.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  5:34 PM
+
+OK, I don't remember seeing this at all (no surprise there, there have been
+something like 250 messages on this topic). In any case, please do not call this
+a "fully dynamic" model, because such a model can't have any compile-time
+checks.
+
+Is that the whole proposal, or is there more to it?? I'm not sure I see the
+point in this case, because the interesting cases are all about putting
+shorter-lived things in longer-lived things (not necessarily directly, but
+safely). But I've probably forgotten that, too.
+
+(I'm really dreading this conference call, because I don't see anything remotely
+resembling convergence on anything that has been discussed -- we all have our
+pet ideas and there doesn't seem to be much interest in considering anyone
+else's very seriously. That's not intended to be a gripe or attack so much as a
+statement of fact -- that's surely how *I* feel on this topic, and I don't see
+much evidence that anyone else is much more open-minded. It is a struggle to
+even try to analyze these ideas without revulsion...)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 11, 2009  5:16 PM
+
+> I'm not personally interested in reinventing Ada 95's
+> anonymous-access-type rules.
+
+Fair enough.
+
+>...I think we can fix
+> some of the mistakes we made in the Ada 2005  additions.
+
+But I'm not interested in fixing "some of the mistakes".
+I say we should do one of:
+
+(1) Accept the status quo, which is a couple of special-purpose Ada 95 gizmos
+    (access parameters and access discriminants), plus a recommendation to
+    avoid using the broken Ada 2005 stuff.
+
+or:
+
+(2) Fix the Ada 2005 stuff so it is simple and useful.
+
+I don't really see how to do (2) without one of the various "ugly" things that
+have been mentioned (and rejected).  I will be convinced only if I can see some
+examples of typical programs that use access types to create heap-based data
+structures, and are in some way "better" than what we currently have.
+
+Replacing "X : Access_Blah;" with "X : access Blah;" doesn't do much, unless it
+avoids bogus conversions, or has some other benefit.
+
+>...I could also imagine some new pragma-restriction  identifiers
+>associated with anonymous access types, such as
+>No_Anonymous_Allocators.  But starting with a  completely different
+>model for anonymous access types  is not good for the language, in my
+>view.
+
+Agreed.  But neither is it good for the language to invent a whole new layer of
+complexity that nobody can understand, causes implementation headaches, and
+still leaves the Ada 2005 stuff in a not-so-useful state.
+
+I really need to go read AI-51...
+
+By the way, note that there is some confusion about what "fully dynamic model"
+means.  Somebody needs to clarify that.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 11, 2009  5:27 PM
+
+> So you had a different idea of what Tucker was proposing than me or Tucker:
+> three people, three different ideas of what was being proposed. This
+> is not good! Tucker needs to write a much more detailed proposal, so
+> we can at least discuss a single idea...
+
+I think there are only two.  That is, my notion agrees with Tucker's notion,
+except I said "exception" where Tucker said "compile-time error" -- but I think
+the truth is, "exception at run-time, but it's always detectable at compile time
+in this sort of case, so you get at least a compile-time warning".
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 11, 2009  5:39 PM
+
+> (Why the heck didn't
+> we call this "lifetime" in the first place? People would understand it
+> better. And yes, I made that suggestion way back in the Ada 9X days,
+> but even then you were too entrenched with the awful terminology of
+> "accessibility" to consider the change.)
+
+During 9X, we made several terminology changes in this area, and (I think) at
+least one version of the documents used "lifetime".  We went round and round in
+circles, and it was always confusing to folks, so I don't think it's a mere
+terminology issue.  It's just hard.
+
+The terms "accessibility" and "deeper than" were invented fairly late in the
+game, as I recall, so I don't think it's fair to say "entrenched".
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  6:24 PM
+
+> I think there are only two.  That is, my notion agrees with Tucker's
+> notion, except I said "exception" where Tucker said "compile-time
+> error" -- but I think the truth is, "exception at run-time, but it's
+> always detectable at compile time in this sort of case, so you get at
+> least a compile-time warning".
+
+Maybe, but what you describe could fairly be called a "fully dynamic model"
+(since warnings don't count), but Tucker is describing static checks, which
+surely aren't included in "fully dynamic". That is, you and Tucker are closer
+together than I was to either of you, but still significantly different.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  6:51 PM
+
+> I'm not personally interested in reinventing Ada 95's
+anonymous-access-type rules.
+
+I happen to think that this focus on "anonymous access" is misguided.
+Accessibility is a mess for all access types, and we ought to consider ways to
+improve that situation for all types. Little patches on the edges of anonymous
+access really don't do much (especially if you don't use them).
+
+So let me throw some additional gasoline on this fire. :-)
+
+For me, the crux of the problem is that 99% of the time, you have to end-run the
+accessibility rules. That is, you have to use 'Unchecked_Access rather than
+'Access for objects almost always. I used to like to say that I had never found
+a case in my actual code where I could actually use 'Access. Unfortunately for
+that statement, I actually found one last month: I needed to put library-level
+objects into a library-level sorting structure. 'Access actually worked. So I
+need a new sound bite.
+
+It sticks me that all of the rigmarole about accessibility is virtually always
+wasted effort. There are only three cases of general interest:
+
+(1) Putting library-level stuff into a library-level structure. (This includes
+    everything allocated from library-level storage pools).
+(2) Creating an access with a very short-lifetime (only as long as the current
+    call or shorter).
+(3) Putting shorter-lived stuff into a library-level data
+    structure (presumably with some outside mechanism, such as finalization, to
+    make it safe).
+
+The current accessibility rules work fine for the first. They sometimes work for
+the second, but not for short lifetime returns. In the third case, no static
+rules have a chance.
+
+Most of my work has involved cases of (3). Thus I never can use 'Access -
+accessibility rules simply get in the way. Indeed, I believe all good ADTs
+should be written to allow the client's objects to be managed by the client,
+including allowing them to be stack allocated, but Ada makes that hard and
+safety is has to be provided by the programmer because the language is actively
+resisting.
+
+Note that putting data structures inside of a main subprogram is technically a
+case of (2), even though in this case, "very short" isn't that short. Probably a
+better description is "no longer than the current call".
+
+If an access type is intended to be used for (1), then it ought to have
+library-level accessibility no matter where it is declared. If an access type is
+intended to be used for (2), then it ought to have call-level accessibility (or
+local accessibility if we find some other way to deal with accessors). If an
+access type is intended to be used for (3), then it ought to have fully dynamic
+accessibility.
+
+This applies equally to anonymous and named access types.
+
+The fact that the accessibility depends mostly on the intended use is the reason
+that I suggested a mechanism for specifying accessibility (with some syntax;
+Tucker's suggestion surely is better than mine).
+
+Unfortunately, I don't think we can make an efficient fully dynamic
+accessibility, so (3) isn't practical. That's more than too bad, it means that
+Ada is doomed for high-level programming (unless we begin to mandate garbage
+collection as an option for some types -- but I don't see how that could be any
+more efficient than proper dangling pointer checks).
+
+One option would be to define an "unchecked" accessibility (meaning that you're
+on your own). But that doesn't help making "good" ADTs easily.
+
+This of course would be easier if we were starting from scratch: in that case,
+every access type would default to library-level accessibility and you would
+have ways to declare something else. But of course that is incompatible, and
+probably too incompatible to do. So I think we're stuck with providing a way to
+declare accessibility on all access types and leaving the current rules alone as
+much as possible.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 11, 2009  7:24 PM
+
+> ...
+> It sticks me that all of the rigmarole about accessibility is
+> virtually always wasted effort. There are only three cases of general interest:
+>
+> (1) Putting library-level stuff into a library-level structure. (This
+> includes everything allocated from library-level storage pools).
+> (2) Creating an access with a very short-lifetime (only as long as the
+> current call or shorter).
+> (3) Putting shorter-lived stuff into a library-level data structure
+> (presumably with some outside mechanism, such as finalization, to make
+> it safe)...
+
+I'm surprised you don't have cases where you have things with modest-length
+lifetime (e.g. for an entire pass of some algorithm).  We certainly have
+situations like that, and 'Access can be useful in that case.  For example, you
+declare a local object of some sort in a procedure, pass 'Access of it to
+something that does a lot of processing, and then on return, the object is
+cleaned up automatically.
+
+I find significant comfort when I can use 'Access rather than 'Unchecked_Access,
+because I know there is one less possible dangling reference to worry about.
+One reason I find the 'Ref proposal so unappealing is that it is essentially
+giving you only what you have in C, with no ability to point to objects on the
+stack without throwing away all checking.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 11, 2009  8:00 PM
+
+I don't think that has ever happened to me, for two^H^H^Hthree reasons:
+(A) I'd rather pass the object itself than an access to it. So if a subsystem needs an access to an object, it has to make the access itself from the parameter (there is a convinient rule that makes all tagged parameters aliased). That falls under case (3
), because the lifetime of the parameter cannot be assumed to be anything in particular.
+(B) In all of the programs that I've written with multiple phases, either each phase is a separate program (Janus/Ada, Jasm), the phases work on a global data structure and don't take any parameters (Jlink, COrder), or the objects that are processed are a
llocated from a (global) storage pool (Trash-Finder, AdaServer). Most of these are older designs; I'm not sure exactly what I'd do today.
+(C) Phases often include multiple calls; there's not necessarily one long-lived processing routine (that's have the Claw Builder is structured).
+The subsystem that processes a phase is at library level.
+
+Even so, this case seems to be exactly the description of case (2): the object
+lives as long as the call of some (single) subprogram. It's the same as
+structures created in the main subprogram, for instance. It's this case that
+justifies some of the complexity of accessibility, I suppose. But in the case
+you described, the access parameter could just as well have call-level
+accessibility, because there is no need to put the object into a longer-lived
+data structure. (If there is such a need, you are again at case (3), where no
+amount of accessibility will help.)
+
+The big problem with access parameters in the case you've described is that if
+you do find (somewhere during that processing) that you need to put the object
+into a global data structure, there is no way to do so. You could abandon the
+execution if you catch the exception or we add the accessibility membership, but
+there is no way to retroactively apply 'Unchecked_Access to the access
+parameter. About all you can do is resort to Unchecked_Conversion, which means
+abandoning type safety as well as dangling pointer safety. That doesn't seem to
+be helping at all. (This is what happened to me when I tried to use access
+parameters in the Claw Builder; I finally gave up and changed the routines in
+question to procedures from functions so I could use "in out" parameters and
+'Unchecked_Access on them when needed.)
+
+> I find significant comfort when I can use 'Access rather than
+> 'Unchecked_Access, because I know there is one less possible dangling
+> reference to worry about.
+
+I agree with that, the problem is that I've been able to use 'Access precisely
+once in the 15 or so years that I've been programming with general access types.
+That's not exactly a lot of comfort. :-) In most of the cases where you are
+getting comfort, I'm using an "in out" parameter so I don't even *need* comfort
+because there is no risk in the first place.
+
+> One reason I find the
+> 'Ref proposal so unappealing is that it is essentially giving you only
+> what you have in C, with no ability to point to objects on the stack
+> without throwing away all checking.
+
+There might be some benefit to that if we can't find a way to do full dynamic
+checking (forcing the use of 'Unchecked_Access everywhere doesn't really help
+anything; a lot of programmers have given up even trying to use 'Access). But
+I'd really like to find a way to handle cases like (3) safely without massive
+overhead. (Unfortunately, everything that has been tried has exactly that.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 11, 2009  8:18 PM
+
+> ...
+> The big problem with access parameters in the case you've described is
+> that if you do find (somewhere during that processing) that you need
+> to put the object into a global data structure, there is no way to do
+> so. You could abandon the execution if you catch the exception or we
+> add the accessibility membership, but there is no way to retroactively
+> apply 'Unchecked_Access to the access parameter. ..
+
+Actually, "A.all'Unchecked_Access" works in most cases.
+
+> ... About all you can do is resort to
+> Unchecked_Conversion, which means abandoning type safety as well as
+> dangling pointer safety.
+
+At least A.all'Unchecked_Access doesn't abandon type safety.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 11, 2009  7:17 PM
+
+> (I'm really dreading this conference call, because I don't see
+> anything remotely resembling convergence on anything that has been
+> discussed -- we all have our pet ideas and there doesn't seem to be
+> much interest in considering anyone else's very seriously.
+
+Well, for what it's worth, I like your idea about allowing safe read/write
+access to components of containers.  Whether or not that involves (anon?) access
+types, I don't know.  At least, I agree that the goal is worthy.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, March 17, 2009  3:57 PM
+
+...
+> Whenever I declare a type T, I have to decide whether to put "type
+> Access_T is access all T" (or maybe T'Class) immediately after, just
+> in case it's needed.
+> If yes, I clutter the program with useless access types.  If no, then
+> I have to create named access types on an as-needed basis, scattered
+> about, and this exacerbates the "bogus type conversion" issue.  Or
+> else I have to go back and modify existing code, which can range from
+> "minor annoyance" to "impossible".
+> I don't like that dilemma.  This explains my point below about 'out'
+> parameters
+> -- I don't like a coding rule that says, "Declare Access_T if and only
+> if you need to have 'out' parameters somewhere else".
+
+I don't understand this at all. (Note to group: yes, I'm violating my own
+request of last night. This paragraph started to bother me this morning and I
+have to say something now.....)
+
+It seems to me that a single named access type should be defined for each
+"big-picture" data structure in a system. (That's presuming that you can't use a
+container for it, which is always the first choice.) By "big-picture" data
+structure, I mean some collection of objects that interrelate; it might be made
+up of several smaller data structures. For instance, in the Trash-Finder spam
+filter, there are a number of queues of messages waiting to be processed in
+different phases. These all share a single access type, because they all belong
+to a single collection of messages being processed.
+
+That is especially important if you want to use a pool (or set of pools in
+Tucker's model) to manage the memory of that big-picture data structure. This
+structuring seems more likely when you have an open package of types (as opposed
+to a "closed" ADT), but I suspect it can happen other ways as well.
+
+In this case, having to explicitly convert between access types seems like an
+advantage: it means that you are converting from one big-picture data structure
+to another -- ideally, you wouldn't do that at all, but in any case it is
+something that should be rare and clearly marked. Anonymous access types are
+actively harmful in this model.
+
+So I don't understand declaring an access type "just in case it is needed".
+It is either clearly needed (because you are going to be defining a collection
+of these objects) or it is something that the client of this type should decide
+(because it is going to decide what data structures will be used). Similarly, I
+don't understand "creating named access types, scattered about"; you'll create
+them where you are creating a big-picture data structure; if there are several
+such structures, then of course there will be several access types. But they'll
+only be as "scattered about" as the data structures; presuming the locations of
+the data structures make sense, so will the locations of the access types.
+
+I guess my main concern is that I'm not the least bit interested in making it
+easier in Ada to create crappy designs. Obviously, we can't outlaw crappy
+designs, and I surely don't want to try, but I don't see any reason to spend
+effort on making it easier.
+
+Now, the original issue that led to the expansion of anonymous access types was
+the use in limited withs. The idea was that anonymous access types could be used
+to build an explicit-conversion-free bridge between a named access type, across
+some code where the named access type is not available, and then back to the
+named access type. The problem is that this does not work in Ada 2005, you must
+use explicit conversions to get back to the named type. I know that the *only*
+reason I did not object to these changes was that I was misled about this
+capability. Had I known that explicit conversions would still be required, I
+would have fought this expansion tooth-and-nail (because then you might as well
+just declare some extra named access types and do the conversions from them -
+you'll have a lot fewer accessibility issues to worry about).
+
+So to me, if we are going to do anything at all, we need to make this original
+promise a reality. Otherwise, let's move the whole lot to Annex J where they
+belong and forget they ever existed.
+
+****************************************************************
+
+========= New thread: Ada-comment discussion of various accessibility ideas =====
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, March 17, 2009  12:54 AM
+
+This message is primarily aimed at Franco Gasperoni, although I have posted it
+here so the rest of you can comment on the ensuing discussion. I'd appreciate it
+if you would refrain from commenting until Franco has had a chance to respond.
+
+Franco, you've on several occasions noted what you consider problems in
+anonymous access types. Bob Duff recently remarked: "Franco and Quentin have
+taught over 100 students object-oriented programming in Ada, and they say that
+it is extremely important to fix these problems".
+
+Just looking at the detailed list of problems you posted in November, it surely
+seems like this is true. But this seems like a very low-level analysis to me.
+I'd like to know more about the object-oriented problems that you are solving
+and how and why you are using anonymous access types in this context. On
+comp.lang.ada, it has nearly become a mantra that a poster needs to explain the
+*problem* they are trying to solve and not necessarily the technique that they
+want to solve it with. And it seems to be a good mantra: Ada really does
+eliminate a lot of the need to use access types that you find in other
+languages.
+
+My point, of course, is that there may be better ways to reach the same goals
+than using anonymous access types. Candidates include (but surely aren't limited
+to) "in out" parameters, containers, and named access types. And I'd like to see
+the actual problems in action, perhaps there is more limited versions of the
+fixes available.
+
+It would be appreciated if you could respond ASAP, as we have a telecon
+scheduled for these issues on Thursday.
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Tuesday, March 17, 2009  12:55 PM
+
+Named access types in Ada are great for abstraction, i.e. to implement a data
+type while hiding the fact that the data type is implemented with a pointer.
+
+When coming to Ada students/developers/... that have been doing OO in other
+languages such as Java or C++ are used to have references/pointers.
+
+The Ada model
+
+    Object : Tagged_Type'Class
+
+is very elegant, works nicely when it comes to OO and behaves elegantly when it
+comes to upcasting.
+
+Unfortunately, in this model we can't dynamically allocate Object, we have to
+initialize Object, and once we've done that we can't change the tag, we can't
+chain these objects in sophisticated data structures. So we need to resort to
+access types.
+
+These access types do not serve the same purpose as what named access types in
+Ada were intended for (i.e. implement a data type by hiding the details). Here
+we really need a "handle" on the actual object and we need to have all the
+semantics associated with the fact that we have a handle.
+
+The handle can point to null, it can point to an object X in D'Class or an
+object Y in B'Class (where D is derived from B). The handle can point to
+dynamically allocated objects.
+
+When we try to do that in Ada 95 or Ada 2005 with the current rules we hit a
+number of traps. That's when we scratch our heads and stare the student in her
+yes when she asks: "Look I am trying to do something very safe here and I can do
+that easily in Java or C++, how do I do the same set of things safely and
+conveniently in Ada".
+
+That's our challenge.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, March 17, 2009  3:55 PM
+
+(BTW, thanks for answering quickly.)
+
+> Named access types in Ada are great for abstraction, i.e. to implement
+> a data type while hiding the fact that the data type is implemented
+> with a pointer.
+
+I don't buy this; there is no hiding implicit in named access types. Sure, you
+can complete a private type with one, but that's a totally different scenario.
+Otherwise you can still see the designated type so they're just as transparent
+as an anonymous access type. There might be a slight advantage in fewer
+conversions, but I think that can be avoided with some care in the usage.
+
+> When coming to Ada students/developers/... that have been doing OO in
+> other languages such as Java or C++ are used to have
+> references/pointers.
+
+OK, but not relevant in building good Ada designs.
+
+> The Ada model
+>
+>     Object : Tagged_Type'Class
+>
+> is very elegant, works nicely when it comes to OO and behaves
+> elegantly when it comes to upcasting.
+
+Right.
+
+> Unfortunately, in this model we can't dynamically allocate Object, we
+> have to initialize Object, and once we've done that we can't change
+> the tag, we can't chain these objects in sophisticated data
+> structures. So we need to resort to access types.
+
+Resort is right. Most of these problems can be dealt with by using one of the
+forms of indefinite containers. (But not always, I admit.) There is some
+annoyances in using the containers, but those areas are weaknesses in the
+abstraction model of Ada generally, and thus are a high priority to be addressed
+in this coming language update. So I see the containers getting easier to use
+with this next version of the language.
+
+> These access types do not serve the same purpose as what named access
+> types in Ada were intended for (i.e. implement a data type by hiding
+> the details). Here we really need a "handle" on the actual object and
+> we need to have all the semantics associated with the fact that we
+> have a handle.
+
+Sorry, that's exactly what an access type (any flavor) is for. I don't see why
+you think there is some abstraction involved in a named access type. Private
+types are something different altogether.
+
+> The handle can point to null, it can point to an object X in D'Class
+> or an object Y in B'Class (where D is derived from B). The handle can
+> point to dynamically allocated objects.
+
+Yes, a named general access type can do all of that.
+
+> When we try to do that in Ada 95 or Ada 2005 with the current rules we
+> hit a number of traps. That's when we scratch our heads and stare the
+> student in her yes when she asks: "Look I am trying to do something
+> very safe here and I can do that easily in Java or C++, how do I do
+> the same set of things safely and conveniently in Ada".
+>
+> That's our challenge.
+
+OK, but why don't named access types work in this context? You seem to think
+they involve some abstraction, but they surely do not necessarily do that. But
+even if they do, shouldn't that be a help rather than a hinderance? Don't you
+want all of the "handles" for a particular data structure (or set of data
+structures) to have the same type, and be notified when you try to convert to
+some other data structure??
+
+Presuming that you can't use a container for some reason, you would then declare
+a named access type for each set of related data structures. You would need
+explicit conversions to go between the sets, but that should be rare.
+
+The one place where this model doesn't work is when you are using limited with.
+In that case, I could see using anonymous access types as a "bridge" until you
+reach a point where the named access type is fully visible. Then you would
+convert back to the named access type. (And, yes, I'm well aware this model
+doesn't work right because it takes an explicit conversion to come back. That is
+a serious bug in Ada 2005, because the only reason I and several other people
+even agreed to expanding anonymous access types was so that this specific case
+would work. That fact that it does not at all work is very, very disturbing to
+me.)
+
+So, what have I missed? I don't think it is ever good practice to scatter types
+about a program, and that applies to any anonymous types as well as any others.
+So I think that good designs should minimize their usage, and I have no interest
+in making writing bad designs in Ada easier. But perhaps there are usage cases I
+have not seen. (I think some examples are going to be needed to be convincing.)
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Tuesday, March 17, 2009  4:31 PM
+
+>> When coming to Ada students/developers/... that have been doing OO in
+>> other languages such as Java or C++ are used to have
+>> references/pointers.
+>
+> OK, but not relevant in building good Ada designs.
+
+But that's today's programmer base and that's the pragmatic reality we must live
+with and nurture.
+
+Today Ada has 3 incomplete access type models, you add a 4th incomplete one
+containers (that in addition it isn't that easy to explain to students).
+
+Is Ada intended for a few experts or for the average intelligence like most of
+us?
+
+Named access types aren't complete. For instance for circular data structures
+(Type A contains a pointer to B and conversely) you need anonymous access. When
+you upcast you need explicit conversions, why?
+
+Named access types are awkward when interfacing to C/C++ and interfacing with
+C/C++ is a reality we must embrace not despise.
+
+All I am asking is a _single_ elegant and safe gizmo (access types named or
+anonymous, containes, whatever you want, but a single one) that can do
+everything that Java references can and as elegantly they can (i.e. I should be
+able to do circular data types, not have to resort to explicit conversions when
+upcasting, ....).
+
+That's all our students are asking for. And it has to be simple to explain.
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Tuesday, March 17, 2009  4:49 PM
+
+There is another crowd I was almost forgetting: those that write UML and that
+generate specs from that. With named access types things are again very
+cumbersome. What answer do we give them (and it has to be the same model we
+explain to students)
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Tuesday, March 17, 2009  4:52 PM
+
+and another one are those that want to reuse C/C++ libraries from Ada. What
+language gizmos do we give to the automatic API bindings builder when it comes
+to pointers?
+
+And how do we export an Ada API with access types to C/C++ folks?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, March 17, 2009  5:21 PM
+
+> >> When coming to Ada students/developers/... that have been doing OO
+> >> in other languages such as Java or C++ are used to have
+references/pointers.
+> >
+> > OK, but not relevant in building good Ada designs.
+>
+> But that's today's programmer base and that's the pragmatic reality we
+> must live with and nurture.
+
+It's still not relevant. If there is a better way to do something in Ada, they
+ought to learn to do that. If they are unwilling/unable to do that, they are
+unlikely to ever be a good Ada programmer.
+
+For me, the argument comes down to whether there is an equivalent (preferably
+better) way to do something in Ada. If there is not, then that is the point at
+which we have a deficiency that needs to be addressed.
+
+> Today Ada has 3 incomplete access type models, you add a 4th
+> incomplete one containers (that in addition it isn't that easy to
+> explain to students).
+
+Containers already exist in Ada 2005; I'm not adding anything. I'm saying you
+need to consider the facilities that are already there before asking for new
+ones.
+
+Containers always come first, IMHO, with new students. I would expect the same
+to be true for C++. You don't start out by reinventing the wheel -- you learn
+how to *use* the wheel first. Once you've done that, then you learn how to
+create new wheels.
+
+As far as ease of use goes, I think it should be a primary goal of this update
+to increase Ada's abstraction facilities (which should make the containers
+easier to use). If we can't do that, we ought not bother doing anything.
+
+In any case, your initial response to this multiplicity of models was to ask for
+another access type model! That makes no sense at all based on this complaint.
+
+> Is Ada intended for a few experts or for the average intelligence like
+> most of us?
+
+If your students already can program successfully in C++, they already a heck of
+a lot smarter than me. ;-)
+
+I think this is at least somewhat a case of wanting to use the same old patterns
+that don't work that well (being very unsafe) and expecting Ada to somehow
+produce better results.
+
+> Named access types aren't complete. For instance for circular data
+> structures (Type A contains a pointer to B and
+> conversely) you need anonymous access. When you upcast you need
+> explicit conversions, why?
+
+I don't follow. The Janus/Ada compiler contains such types and it was built in
+Ada 83. Surely we didn't use any anonymous access types!
+
+Perhaps you are talking about limited with. I specifically mentioned that the
+model in that one specific case is badly broken; but I'm not sure there is any
+will to do anything about it.
+
+> Named access types are awkward when interfacing to C/C++ and
+> interfacing with C/C++ is a reality we must embrace not despise.
+
+Why? Since C/C++ doesn't have any real nesting, library-level accesses are good
+enough for most uses. (Named accesses are easier to ensure have convention C, as
+well.) And finally, the vast majority of *T parameters should be mapped to in
+out T (indeed, that is explicitly supported by the RM). Claw's bindings to Win32
+use few anonymous access parameters (less than 1 out of 10, probably far less, I
+didn't do a formal count). In hindsight, I think we could have used fewer still
+anonymous access parameters, but we were not clear on which parameters were real
+accesses and which are just "in out". (That's really a problem on the C side,
+not the Ada side.)
+
+> All I am asking is a _single_ elegant and safe gizmo (access types
+> named or anonymous, containes, whatever you want, but a single one)
+> that can do everything that Java references can and as elegantly they
+> can (i.e. I should be able to do circular data types, not have to
+> resort to explicit conversions when upcasting, ....).
+
+I would like to see some examples of the problems that you are having, so I can
+show you how I would write them. And then we'll both have a better idea where
+the other is coming from.
+
+The problem here is that you assert these things, and I don't doubt that you
+believe them, but I continue to think that there is a better way that you are
+not seeing. But if I'm wrong, I'd like to know it, and that takes
+counter-examples.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, March 17, 2009  5:32 PM
+
+> and another one are those that want to reuse C/C++ libraries from Ada.
+> What language gizmos do we give to the automatic API bindings builder
+> when it comes to pointers?
+
+Doesn't much matter, because the only value of such a binding builder is to
+reduce the errors in creating a thin binding (that is, writing the actual pragma
+Imports). Under no circumstances that I've ever seen would you use such a thing
+without building another abstraction on top of it to make it Ada-like. And that
+has to be done by hand, and properly designed. If you don't do that, you lose
+90% of the benefits of Ada and might even be worse off than just having written
+the whole thing in C/C++.
+
+> And how do we export an Ada API with access types to C/C++ folks?
+
+I don't think this is a particularly important problem; most new code that's not
+in Ada is likely to be in a web language these days. Moreover, I don't see any
+problem with doing this (at least for C) -- we did plenty of interfacing for
+Claw in straight Ada 95.
+
+As far as interfacing tagged types to C++, we have pretty much given up on
+finding any model that would work in Ada for that. A particular implementation
+may be able to pull it off by sticking restrictions on the Ada side, but those
+are not appropriate for the Ada language. So I think this will remain
+implementation-specific at best.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, March 17, 2009  5:47 PM
+
+...
+> I would like to see some examples of the problems that you are having,
+> so I can show you how I would write them. And then we'll both have a
+> better idea where the other is coming from.
+>
+> The problem here is that you assert these things, and I don't doubt
+> that you believe them, but I continue to think that there is a better
+> way that you are not seeing. But if I'm wrong, I'd like to know it,
+> and that takes counter-examples.
+
+Given that time is rather short for this round, I'm most interested in the
+problems that you think can't be solved by any Ada access types (named or
+anonymous). I find that claim rather curious and would like to see what problems
+you are having (preferably in a larger context). I'm less interested in the
+anonymous access type, because by definition it is a less powerful cousin to
+named access type (and I would need very strong reasons to support any expansion
+in capabilities).
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Wednesday, March 18, 2009  1:36 AM
+
+>> and another one are those that want to reuse C/C++ libraries from
+>> Ada. What language gizmos do we give to the automatic API bindings
+>> builder when it comes to pointers?
+>
+> Doesn't much matter, because the only value of such a binding builder
+> is to reduce the errors in creating a thin binding (that is, writing
+> the actual pragma Imports). Under no circumstances that I've ever seen
+> would you use such a thing without building another abstraction on top
+> of it to make it Ada-like. And that has to be done by hand, and
+> properly designed. If you don't do that, you lose 90% of the benefits
+> of Ada and might even be worse off than just having written the whole thing in C/C++.
+
+That is not my experience, for instance when you are doing a binding to .net or
+to java libraries. That can be completely automated and you get a very nice and
+elegant thick binding that today cannot work because of todays' limitations of
+anonymous access.
+
+>> And how do we export an Ada API with access types to C/C++ folks?
+>
+> As far as interfacing tagged types to C++, we have pretty much given up on
+> finding any model that would work in Ada for that.
+
+We haven't and it isn't that hard if the C++ ABI is used on the C++ side. The
+problem again is that there isn't a single access type model that works in Ada.
+Anonymous access are the ones to come closer but as we all discovered they are
+broken.
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Wednesday, March 18, 2009  11:01 AM
+
+> My point, of course, is that there may be better ways to reach the same
+> goals than using anonymous access types. Candidates include (but surely
+> aren't limited to) "in out" parameters, containers, and named access types.
+
+
+Randy, let me try another route in trying to explain the problem we are facing.
+
+As a side note I agree with you that in certain situations containers or
+wrappers in general can hide the mechanics of Ada access types.
+
+Unfortunately, containers cannot always be used, for instance when creating
+general graph-like data structures, when access time and memory management must
+be addressed very finely for performance reasons, when developing a
+safety-critical application where only simple data structures (e.g. a few linked
+lists) are needed and the developer does not want to certify a whole containers
+library.
+
+In the following I would like to focus on those cases where you cannot use
+containers.
+
+For "in out" parameters I also agree that using access types to simulate "in
+out" in functions is an abnormal situation and we should just have "in out" in
+functions.
+
+So I'd like to focus on why named general access parameters aren't enough.
+
+Why Named Access isn't enough
+-----------------------------
+Let's assume we decided not to use anonymous access ever and just decided to use
+general named access.
+
+First hurtle:
+------------
+   type Access_B is access all B;
+   type B is record
+      ...
+      XC: Access_C
+   end record;
+
+   type Access_C is access all C;
+   type C is record
+      ...
+      XB : Access_B;
+   end record;
+
+for the above to work we must put them in the same package. To put them in
+separate packages "limited with" does not help us, we would have to use
+anonymous access. When doing a binding to C/C++/Java that is a deal breaker. So
+in this case (when doing a C/C++/Java) binding we have to use "limited with" and
+anonymous access.
+
+You mentioned this problem in one of your emails.
+
+
+Second Hurtle:
+-------------
+Ada *forces* us to mix anonymous and named access types when it comes to OO.
+
+    type B is tagged record ...
+    type Access_B is access all B;
+    procedure P (XB : Access_B);
+
+P is not a primitive operation: we *have* to use anonymous access arghhhhh.
+But anonymous access types are broken :( :(
+
+One could say, why don't you write
+
+     procedure P (XB : access B) is
+        Local : Access_B : Access_B (XB);
+
+and use local inside P. That is an ackward work-around that does not help us
+against the call to
+
+     P (new B)
+
+which depending on the context where P is called will raise an exception when
+assigning to Local inside P and if no assignment is make does not guarantee that
+we can free the allocation safely.
+
+The workaround here would be to have
+
+    Another_Local : Access_B := new B;
+    P (Another_Local);
+
+admittedly the code starts to be sprinkled with all the spurious variables whose
+sole purpose is work around Ada's double general access type model :(
+
+
+Third Hurtle
+------------
+Burdening upcast conversions in OO.
+
+    type B is tagged record ...
+    type Any_B is access all B'Class;
+
+    type D is new B with record ...
+    type Any_D is access all D'Class;
+
+Quentin faces this issue very often. Assume we have a container of Any_B and in
+the code we have
+
+    D_Ref : Any_D := new D;
+    ...
+
+when we add D_ref to the container we need to write
+
+    Add (Container, Any_B (D_Ref));
+
+This upcasting conversion is what Bob calls crying wolf and is very annoying
+because Ada teaches us that conversions are potentially dangerous places and
+should be reviewed carefully and in the above example it is simply not true.
+
+
+Way Out?
+-------
+(a) Fix anonymous access. Have Tuck's generalized dynamic accessibility rule
+complemented with the guarantee that "new" (allocators) allocate from the heap
+irrespective of the context and that these allocations can be safely deallocated.
+
+(b) Get rid of anonymous access alltogether and give the ability to named
+general access to create primitive ops, create circular data types with limited
+with and avoid useless upcasting conversions (perhaps by allowing a subtype of
+a named like
+
+    type B is tagged record ...
+    type Any_B is access all B'Class;
+
+    type D is new B with record ...
+    subtype Any_D is Any_B access D'Class;
+
+(c) Change the semantics of
+
+           Object : B'Class
+
+     to be by reference rather than by value (ie Object would be a reference to
+a B'Class object and it would be initialized to null if no initialization is
+provided etc etc)
+
+(d) Use Array indeces as we do in SPARK.
+
+****************************************************************
+
+From: Simon Wright
+Sent: Wednesday, March 18, 2009  12:29 PM
+
+> There is another crowd I was almost forgetting: those that write UML
+> and that generate specs from that. With named access types things are
+> again very cumbersome. What answer do we give them (and it has to be
+> the same model we explain to students)
+
+As one of that crowd -- albeit to Ada95 -- I don't see the problem. A class in
+UML will be translated using an appropriate mapping rule, which people just have
+to learn. Ours uses Instances and Handles;
+
+package Instances is
+type Instance_Base is abstract tagged limited private; type Handle is access all Instance_Base'Class; for Handle'Storage_Size use 0;
+
+with Instances;
+package Gen_Class is
+type Instance (<>) is new Instances.Instance_Base with private; type Handle is access all Instance;
+
+Conversions to/from Instances.Handle aren't that common, when they do occur it's
+an idiom that people (have to) get used to. Some of the need for user-written
+conversions goes away because code for associations between classes is
+automatically generated, and does the necessary conversions behind the scenes.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 18, 2009  2:15 PM
+
+> > Doesn't much matter, because the only value of such a binding
+> > builder is to reduce the errors in creating a thin binding (that is,
+> > writing the actual pragma Imports). Under no circumstances that I've
+> > ever seen would you use such a thing without building another
+> > abstraction on top of it to make it Ada-like. And that has to be
+> > done by hand, and properly designed. If you don't do that, you lose
+> > 90% of the benefits of Ada and might even be worse off than just
+> > having written
+> the whole thing in C/C++.
+>
+> That is not my experience, for instance when you are doing a binding
+> to .net or to java libraries. That can be completely automated and you
+> get a very nice and elegant thick binding that today cannot work
+> because of todays' limitations of anonymous access.
+
+OK, but I still disagree. Ada is not a reference language! You have to get rid
+of access types that aren't managed by Ada and any special conventions from any
+interface before it is a "good" interface in my opinion. (A good interface does
+not dictate the storage management to its clients.) It's completely impossible
+to do that automatically for Java (which *is* a reference language), and dubious
+for C++.
+
+> >> And how do we export an Ada API with access types to C/C++ folks?
+> >
+> > As far as interfacing tagged types to C++, we have pretty much given
+> > up on
+> > finding any model that would work in Ada for that.
+>
+> We haven't and it isn't that hard if the C++ ABI is used on the C++ side. The
+> problem again is that there isn't a single access type model that
+> works in Ada.
+> Anonymous access are the ones to come closer but as we all discovered
+> they are broken.
+
+Well, as I said, a single Ada compiler might be able to pull it off, but such
+things are not possible for Ada (that is, the Ada Standard):
+
+(1) It would be inappropriate for the Ada Standard to require that all tagged
+types (for instance) be implemented as in C++ (or any other single language).
+Obviously, there might not even be a C++ available for the target, and in any
+case, such requirements would doom Ada to mediocrity: it would be impossible to
+be *better* than C++ on various issues. One example: Janus/Ada does tag trimming
+(that is, removing primitive subprograms that cannot be called, even through a
+tag). That wouldn't be possible if we used C++ tags, as we would not be able to
+tell statically which dispatching C++ calls are made.
+
+(2) In general, there is no such thing as a C++ ABI. Compilers rarely document
+the interfaces used for tags; using undocumented facilities is fraught with
+problems. And documents that do exist are often wrong or misleading (defining
+capabilities that don't actually work). We had to reverse-engineer the C
+compilers on various targets to find out what they *really* do before trying to
+interface to them. (Originally, we believed the documents and spent a lot of
+effort building tools that didn't actually work.) Again, a particular
+implementation may not have this problem, for instance an open source
+implementation such as GNAT interfacing to an open source C++ probably can just
+examine the appropriate source code in the worst case. But surely the Ada
+Standard should not practically prevent the usage of proprietary compilers.
+
+These issues mean it doesn't make sense for the Ada Standard to try to define
+such interfaces.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 18, 2009  3:33 PM
+
+> Unfortunately, containers cannot always be used, for instance when
+> creating general graph-like data structures, when access time and
+> memory management must be addressed very finely for performance
+> reasons, when developing a safety-critical application where only
+> simple data structures (e.g. a few linked lists) are needed and the
+> developer does not want to certify a whole containers library.
+
+I agree in general, although the last point seems irrelevant to your concerns,
+as such a project would never use tagged types or dispatching or dynamic
+allocation either. So they couldn't run into any of the issues you are having.
+
+> In the following I would like to focus on those cases where you cannot
+> use containers.
+>
+> For "in out" parameters I also agree that using access types to
+> simulate "in out" in functions is an abnormal situation and we should
+> just have "in out" in functions.
+>
+> So I'd like to focus on why named general access parameters aren't
+> enough.
+>
+> Why Named Access isn't enough
+> -----------------------------
+> Let's assume we decided not to use anonymous access ever and just
+> decided to use general named access.
+
+Sounds like a good general plan.
+
+> First hurtle:
+> ------------
+>    type Access_B is access all B;
+>    type B is record
+>       ...
+>       XC: Access_C
+>    end record;
+>
+>    type Access_C is access all C;
+>    type C is record
+>       ...
+>       XB : Access_B;
+>    end record;
+>
+> for the above to work we must put them in the same package.
+> To put them in separate packages "limited with" does not help us, we
+> would have to use anonymous access. When doing a binding to C/C++/Java
+> that is a deal breaker.
+> So in this case (when doing a C/C++/Java) binding we have to use
+> "limited with"
+> and anonymous access.
+>
+> You mentioned this problem in one of your emails.
+
+Yes, this is the exception where you need some other mechanism. Preferably one
+that works!
+
+One option of course is to return to the original model and require all access
+types to have a single representation. In that case, limited with of named
+access types can work. But it means abandoning pools and stream attributes, so
+it doesn't seem very promising as an approach. One could imagine a keyword to
+allow such an export (it would have to be syntactic in order to work), and allow
+the full generality otherwise. Still seems limiting, but definitely an
+alternative.
+
+> Second Hurtle:
+> -------------
+> Ada *forces* us to mix anonymous and named access types when it comes
+> to OO.
+>
+>     type B is tagged record ...
+>     type Access_B is access all B;
+>     procedure P (XB : Access_B);
+>
+> P is not a primitive operation: we *have* to use anonymous access
+> arghhhhh.
+> But anonymous access types are broken :( :(
+
+Repeat after me: Ada is not a reference language. Ada is not a reference
+language. :-) Ada is an object language (where I'm using "object" in it's Ada
+sense; O-O dogma gives this concept a different name which I forget at the
+moment. Ada logically operates directly on objects and does not show the
+"under-the-hood" references very often. It's this nature that allows Ada O-O
+objects to be stack allocated, directly placed in containers, etc.
+
+Thus, dispatching on access values is fundamentally not Ada. I know that a
+number of us opposing having any solution to this problem in Ada 95, but were
+squashed because of the lack of "in out" parameters on functions. Just because
+other languages are designed this way does not mean that Ada should be. (The
+fact that other people smoke dope does not mean that we should also be smoking
+dope!!)
+
+Therefore, procedure P ought to properly be written as:
+
+   procedure P (XB : in out B);
+
+And .all passed when needed. (This has the appropriate side effect of making the
+fact that XB cannot be null obvious, although at least you can do that
+optionally in Ada 2005.)
+
+If you need an access of XB inside of the body of P, you can write
+XB'Unchecked_Access.
+
+> One could say, why don't you write
+>
+>      procedure P (XB : access B) is
+>         Local : Access_B : Access_B (XB);
+>
+> and use local inside P.
+
+That's almost exactly what you should do:
+
+      procedure P (XB : in out B) is
+         Local : Access_B : Access_B (XB'Unchecked_Access);
+
+You are going to complain about the lose of safety (because of the potential for
+dangling accesses). I agree; I've been searching for a way to make this safe
+automatically for years, but such ways are pretty expensive. (Both the runtime
+accessibility check and the parameter passing of tagged objects would require
+runtime overhead whether or not the feature is used.
+
+The real issue here is that we need to be able to manage the lifetime of
+accesses dynamically, and no such way exists automatically. The best I can do is
+make B controlled and have its finalization routine clean up any lingering
+messes (such as global lists that it is saved on). This (when done right) works
+perfectly (Claw uses this approach, for instance), but it isn't easy and
+requires overhead on the design of objects.
+
+But the only practical alternative to this design is to turn Ada into a
+reference language, not only requiring your original code to work but also to
+require garbage collection (because storage management is impossible if you are
+passing references through) and ban the use of stack allocation and container
+allocation (using references in their places). This seems like a massive change
+to the Ada model, and at odds with the needs of the avionics folks among others.
+I don't see how we can do that.
+
+> That is an ackward work-around that
+> does not help us against the call to
+>
+>      P (new B)
+>
+> which depending on the context where P is called will raise an
+> exception when assigning to Local inside P and if no assignment is
+> make does not guarantee that we can free the allocation safely.
+
+Allocators of anonymous access types should never have been allowed in the first
+place. Now that we have them, they can't be fixed. (See below.)
+
+> The workaround here would be to have
+>
+>     Another_Local : Access_B := new B;
+>     P (Another_Local);
+>
+> admittedly the code starts to be sprinkled with all the spurious
+> variables whose sole purpose is work around Ada's double general
+> access type model :(
+
+If allocations are "sprinkled all over", there is something very wrong with the
+design of your program. Allocations ought to belong to a particular "collection"
+of objects (potentially shared amongst a set of data structures), and for that
+purpose, a named access type makes sense. (I'm using "collection" informally
+here, not in the Ada sense.) Allocations that are not clearly part of some
+collection are impossible to manage and can't be deallocated safely in any way.
+The only hope for them is to use garbage collection, which is not a required
+part of the Ada model. Thus, in the absence of garbage collection, such
+allocators are downright dangerous.
+
+I realize that I hold a minority opinion here. But I am strongly against making
+it easier to create bad designs in Ada. If it is impossible, then I have some
+sympathy, but making it easy is actively harmful.
+
+
+> Third Hurtle
+> ------------
+> Burdening upcast conversions in OO.
+
+Without the below example, I would have no idea what you meant by "upcast". I
+would have called them "downcast" since they are going toward the root (and the
+roots of all [real] trees that I know of are on the bottom). But it would be
+better to say "toward the root" and eliminate all doubt.
+
+>     type B is tagged record ...
+>     type Any_B is access all B'Class;
+>
+>     type D is new B with record ...
+>     type Any_D is access all D'Class;
+>
+> Quentin faces this issue very often. Assume we have a container of
+> Any_B and in the code we have
+>
+>     D_Ref : Any_D := new D;
+>     ...
+>
+> when we add D_ref to the container we need to write
+>
+>     Add (Container, Any_B (D_Ref));
+>
+> This upcasting conversion is what Bob calls crying wolf and is very annoying
+> because Ada teaches us that conversions are potentially dangerous places and
+> should be reviewed carefully and in the above example it is simply not true.
+
+I tend to believe that all conversions between access types should have a
+conversion. That's because you are moving the object from one "collection" to
+another, and that should happen only rarely. Most of the cases where this
+happened in the various Claw programs and tools, we handled it using dispatching
+rather than a conversion.
+
+Anonymous access types are explicitly intended to avoid conversions, and thus
+should be used very sparingly and only as a "bridge" in cases where the named
+type that defines a "collection" isn't available (i.e. limited with).
+
+I am strongly against "sprinkling" any types throughout the code, which makes
+anonymous access types harmful in most circumstances.
+
+Could you explain why you need two different types to point at objects that
+clearly belong to the same collection? That seems like a design problem to me,
+but there may be a good reason that I'm missing.
+
+> Way Out?
+> -------
+> (a) Fix anonymous access. Have Tuck's generalized dynamic
+> accessibility
+rule
+> complemented with the guarantee that "new" (allocators) allocate from
+> the
+heap
+> irrespective of the context and that these allocations can be safely
+> deallocated.
+
+This latter would be the worst kind of incompatibility (technically, an "inconsistency"). Programs written on compilers that provide the behavior suggested by the current Implementation Advice would still compile and most likely would pass their tests, bu
t they would be leaking memory. Which probably would run out at the worst possible time in a deployed system (for instance, during landing of an aircraft).
+
+Remember, this is an Ada 95 feature and lots of deployed programs probably depend on it in some way. Janus/Ada does issue a warning about leaking on such allocators, but we can get away with that because we never implemented the IA. Compilers that did imp
lement that IA couldn't do so.
+
+We could make such allocators illegal (that would tell users at compile-time to change their code), but I don't think that I can convince the others to make such a change. The best I'm hoping for is a restriction pragma, which admittedly is almost no help
 at all.
+
+We probably can make limited fixes to anonymous access types to fix the limited
+with problem and perhaps some others without too much incompatibility, but I'm
+pretty sure we can't give you your nirvana.
+
+> (b) Get rid of anonymous access alltogether and give the ability to
+> named general access to create primitive ops, create circular data
+> types with limited
+> with and avoid useless upcasting conversions (perhaps by allowing a
+> subtype of a named like
+>
+>     type B is tagged record ...
+>     type Any_B is access all B'Class;
+>
+>     type D is new B with record ...
+>     subtype Any_D is Any_B access D'Class;
+
+This is another option. The latter idea is interesting, although I'd like a
+better explanation of the need.
+
+> (c) Change the semantics of
+>
+>            Object : B'Class
+>
+>      to be by reference rather than by value (ie Object would be areference to
+> a B'Class object and it would be initialized to null if no
+> initialization is
+> provided etc etc)
+
+I suspect that this too would be way too incompatible. (But it is much more in
+line with the way I would like to see the language evolve. The most likely
+problem would be with those pesky avionics applications that can't handle
+dynamic allocation.)
+
+> (d) Use Array indeces as we do in SPARK.
+
+??? Is this supposed to be a joke? The smiley is missing.
+
+I'd add (e):
+
+(e) Tell people that Ada is just fine as it is and they should use it properly.
+
+<Grin>
+
+****************************************************************
+
+From: Martin Dowie
+Sent: Wednesday, March 18, 2009  3:56 PM
+
+>> Unfortunately, containers cannot always be used, for instance when
+>> creating general graph-like data structures, when access time and
+>> memory management must be addressed very finely for performance
+>> reasons, when developing a safety-critical application where only
+>> simple data structures (e.g. a few linked lists) are needed and the
+>> developer does not want to certify a whole containers library.
+>
+> I agree in general, although the last point seems irrelevant to your
+> concerns, as such a project would never use tagged types or
+> dispatching or dynamic allocation either. So they couldn't run into
+> any of the issues you are having.
+
+That's not entirely true... I've been involved in safety-critical apps that use
+dynamic allocation - provided the memory allocation is done during an
+'initialisation' phase and there is no re-allocation or further claims later. I
+can't remember off hand about de-allocation...
+
+And SPARK has allowed tagged types since Issue 2.3 of the Reference
+SPARK95 doc.
+
+I can't say whether there are any safety-critical apps that bump into Franco's
+problem though!
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Wednesday, March 18, 2009  4:34 PM
+
+>> Unfortunately, containers cannot always be used, for instance when
+>> creating general graph-like data structures, when access time and
+>> memory management must be addressed very finely for performance
+>> reasons, when developing a safety-critical application where only
+>> simple data structures (e.g. a few linked lists) are needed and the
+>> developer does not want to certify a whole containers library.
+>
+> I agree in general, although the last point seems irrelevant to your
+> concerns, as such a project would never use tagged types or
+> dispatching or dynamic allocation either. So they couldn't run into
+> any of the issues you are having.
+
+They do use tagged types and dispatching in a certified level A application we
+have customers that do exactly that and I'd bet you'll be flying on one of those
+in the future :)
+
+
+>> First hurtle:
+>> ------------
+>>    type Access_B is access all B;
+>>    type B is record
+>>       ...
+>>       XC: Access_C
+>>    end record;
+>>
+>>    type Access_C is access all C;
+>>    type C is record
+>>       ...
+>>       XB : Access_B;
+>>    end record;
+ >
+> attributes, so it doesn't seem very promising as an approach. One
+> could imagine a keyword to allow such an export (it would have to be
+> syntactic in order to work), and allow the full generality otherwise.
+> Still seems limiting, but definitely an alternative.
+
+worth trying - if you can come up with a model where we never need anonymous
+access then we clearly have solved the problem one way
+
+>
+>> Second Hurtle:
+>> -------------
+>> Ada *forces* us to mix anonymous and named access types when it comes
+>> to OO.
+>>
+>>     type B is tagged record ...
+>>     type Access_B is access all B;
+>>     procedure P (XB : Access_B);
+>>
+>> P is not a primitive operation: we *have* to use anonymous access
+>> arghhhhh.
+>> But anonymous access types are broken :( :(
+>
+> Repeat after me: Ada is not a reference language. Ada is not a
+> reference language. :-) Ada is an object language (where I'm using
+> "object" in it's Ada sense; O-O dogma gives this concept a different
+> name which I forget at the moment. Ada logically operates directly on
+> objects and does not show the "under-the-hood" references very often.
+> It's this nature that allows Ada O-O objects to be stack allocated, directly placed in containers, etc.
+>
+> Thus, dispatching on access values is fundamentally not Ada. I know
+> that a number of us opposing having any solution to this problem in
+> Ada 95, but were squashed because of the lack of "in out" parameters
+> on functions. Just
+
+certainly it is time to have "in out" in functions regardless of this discussion
+
+> because other languages are designed this way does not mean that Ada
+> should be. (The fact that other people smoke dope does not mean that
+> we should also be smoking dope!!)
+>
+> Therefore, procedure P ought to properly be written as:
+>
+>    procedure P (XB : in out B);
+>
+> And .all passed when needed. (This has the appropriate side effect of
+> making the fact that XB cannot be null obvious, although at least you
+> can do that optionally in Ada 2005.)
+>
+> If you need an access of XB inside of the body of P, you can write
+> XB'Unchecked_Access.
+
+Ahah - if you do that than all is well, and may be that is a path to pursue but
+then let's not call it 'Unchecked_Access let's just called it 'Pointer  :) It
+would be nice if it was safe but at this boint it does not look like we can have
+the cake and eat it too, tools like Tuck's can worry about safety or may be that
+can be done via pre-conditions (such as never pass a local object).
+
+Seriously if you consider the above good safe Ada style then most of my problems
+are solved (provided we can also call it 'XXX where XXX is something short :)
+
+>
+>> One could say, why don't you write
+>>
+>>      procedure P (XB : access B) is
+>>         Local : Access_B : Access_B (XB);
+>>
+>> and use local inside P.
+>
+> That's almost exactly what you should do:
+>
+>       procedure P (XB : in out B) is
+>          Local : Access_B : Access_B (XB'Unchecked_Access);
+>
+> You are going to complain about the lose of safety (because of the
+> potential for dangling accesses). I agree; I've been searching for a
+> way to make this safe automatically for years, but such ways are
+> pretty expensive. (Both the runtime accessibility check and the
+> parameter passing of tagged objects would require runtime overhead whether or not the feature is used.
+>
+
+Another way is via preconditions on P that would tell clients that you can't
+pass it local objects
+
+
+> The real issue here is that we need to be able to manage the lifetime of
+> accesses dynamically, and no such way exists automatically.
+
+right....
+
+> The best I can
+> do is make B controlled and have its finalization routine clean up any
+> lingering messes (such as global lists that it is saved on). This (when done
+> right) works perfectly (Claw uses this approach, for instance), but it isn't
+> easy and requires overhead on the design of objects.
+
+right controlled types can be fairly heavy artillery, also it would be nice if
+controlled was just an interface that could be implemented rather than a root
+type we must derive from....
+
+>
+> But the only practical alternative to this design is to turn Ada into a
+> reference language, not only requiring your original code to work but also
+> to require garbage collection (because storage management is impossible if
+> you are passing references through) and ban the use of stack allocation and
+> container allocation (using references in their places). This seems like a
+> massive change to the Ada model, and at odds with the needs of the avionics
+> folks among others. I don't see how we can do that.
+>
+
+The issue is not to ban it but allow both models to exist and then you chose
+one or the other. Also note that we have customers that use OO tagged types try
+to use anonymous access (with pain) but don't do dynamic allocation (you can
+preallocate everything and never need to deallocate). We don't have an answer
+for  these folks.
+
+Also Air traffic management apps (and there are lots in ADa) are not
+constrained by no dynamic allocation and they would also like to have the
+option to use Ada as a safe reference language.
+
+So Ada should be both a safe object and a reference language, it should make a
+choice it should let the developer chose.
+
+>> That is an ackward work-around that
+>> does not help us against the call to
+>>
+>>      P (new B)
+>>
+>> which depending on the context where P is called will raise
+>> an exception when assigning to Local inside P and if no
+>> assignment is make does not guarantee that we can free the
+>> allocation safely.
+>
+> Allocators of anonymous access types should never have been allowed in the
+> first place. Now that we have them, they can't be fixed. (See below.)
+>
+
+They must be fixed or forbidden.
+
+>> The workaround here would be to have
+>>
+>>     Another_Local : Access_B := new B;
+>>     P (Another_Local);
+>>
+>> admittedly the code starts to be sprinkled with all the
+>> spurious variables whose sole purpose is work around Ada's
+>> double general access type model :(
+>
+> If allocations are "sprinkled all over", there is something very wrong with
+> the design of your program. Allocations ought to belong to a particular
+> "collection" of objects (potentially shared amongst a set of data
+> structures), and for that purpose, a named access type makes sense. (I'm
+> using "collection" informally here, not in the Ada sense.) Allocations that
+> are not clearly part of some collection are impossible to manage and can't
+> be deallocated safely in any way. The only hope for them is to use garbage
+> collection, which is not a required part of the Ada model. Thus, in the
+> absence of garbage collection, such allocators are downright dangerous.
+
+and should forbidden :)
+
+>
+> I realize that I hold a minority opinion here. But I am strongly against
+> making it easier to create bad designs in Ada. If it is impossible, then I
+> have some sympathy, but making it easy is actively harmful.
+>
+
+then let's forbid such allocators. better to forbid then create hazards
+
+>
+>> Third Hurtle
+>> ------------
+>> Burdening upcast conversions in OO.
+>
+> Without the below example, I would have no idea what you meant by "upcast".
+> I would have called them "downcast" since they are going toward the root
+> (and the roots of all [real] trees that I know of are on the bottom). But it
+> would be better to say "toward the root" and eliminate all doubt.
+>
+>>     type B is tagged record ...
+>>     type Any_B is access all B'Class;
+>>
+>>     type D is new B with record ...
+>>     type Any_D is access all D'Class;
+>>
+>> Quentin faces this issue very often. Assume we have a
+>> container of Any_B and in the code we have
+>>
+>>     D_Ref : Any_D := new D;
+>>     ...
+>>
+>> when we add D_ref to the container we need to write
+>>
+>>     Add (Container, Any_B (D_Ref));
+>>
+>> This upcasting conversion is what Bob calls crying wolf and is very
+> annoying
+>> because Ada teaches us that conversions are potentially dangerous places
+> and
+>> should be reviewed carefully and in the above example it is simply not
+> true.
+>
+> I tend to believe that all conversions between access types should have a
+> conversion. That's because you are moving the object from one "collection"
+> to another, and that should happen only rarely. Most of the cases where this
+> happened in the various Claw programs and tools, we handled it using
+> dispatching rather than a conversion.
+>
+> Anonymous access types are explicitly intended to avoid conversions, and
+> thus should be used very sparingly and only as a "bridge" in cases where the
+> named type that defines a "collection" isn't available (i.e. limited with).
+>
+> I am strongly against "sprinkling" any types throughout the code, which
+> makes anonymous access types harmful in most circumstances.
+>
+> Could you explain why you need two different types to point at objects that
+> clearly belong to the same collection? That seems like a design problem to
+> me, but there may be a good reason that I'm missing.
+
+Quentin?
+
+>
+>> Way Out?
+>> -------
+>> (a) Fix anonymous access. Have Tuck's generalized dynamic accessibility
+> rule
+>> complemented with the guarantee that "new" (allocators) allocate from the
+> heap
+>> irrespective of the context and that these allocations can be
+>> safely deallocated.
+>
+> This latter would be the worst kind of incompatibility (technically, an
+> "inconsistency"). Programs written on compilers that provide the behavior
+> suggested by the current Implementation Advice would still compile and most
+> likely would pass their tests, but they would be leaking memory. Which
+> probably would run out at the worst possible time in a deployed system (for
+> instance, during landing of an aircraft).
+>
+> Remember, this is an Ada 95 feature and lots of deployed programs probably
+> depend on it in some way. Janus/Ada does issue a warning about leaking on
+> such allocators, but we can get away with that because we never implemented
+> the IA. Compilers that did implement that IA couldn't do so.
+>
+> We could make such allocators illegal (that would tell users at compile-time
+> to change their code),
+
+Why not, let's make them illegal in Ada 2012, this can only help portabbility
+and safety!
+
+> We probably can make limited fixes to anonymous access types to fix the
+> limited with problem and perhaps some others without too much
+> incompatibility, but I'm pretty sure we can't give you your nirvana.
+
+An object model that works without 'Unchecked_Access is fine.
+One were the user has a choice bw object model and reference model is fine
+It's the current state of things that I find problematic and you clearly agree
+with me. Let's not stick to status quo.
+
+If we all agree that Ada is not a reference language then let's get rid of all
+this anonymous access nonsense, and if we agree that Ada should offer the
+option to developers to be a reference language then let's fix them.
+
+
+>
+>> (b) Get rid of anonymous access alltogether and give the ability to named
+>> general access to create primitive ops, create circular data types with
+> limited
+>> with and avoid useless upcasting conversions (perhaps by allowing a
+> subtype of
+>> a named like
+>>
+>>     type B is tagged record ...
+>>     type Any_B is access all B'Class;
+>>
+>>     type D is new B with record ...
+>>     subtype Any_D is Any_B access D'Class;
+>
+> This is another option. The latter idea is interesting, although I'd like a
+> better explanation of the need.
+
+then may be this is something to explore. The idea is to mimick
+
+   type B is range 1 ..1_000;
+   subtype D is B range 100 .. 300;
+
+for the same reasons
+
+>
+>> (c) Change the semantics of
+>>
+>>            Object : B'Class
+>>
+>>      to be by reference rather than by value (ie Object would be a
+> reference to
+>> a B'Class object and it would be initialized to null if no initialization
+> is
+>> provided etc etc)
+>
+> I suspect that this too would be way too incompatible. (But it is much more
+> in line with the way I would like to see the language evolve. The most
+> likely problem would be with those pesky avionics applications that can't
+> handle dynamic allocation.)
+
+we don;t need dynamic applications things can be allocated from preallocated
+arrays (and objects never deallocated). Another way is an idea that Bo had
+where you would tell the max size that any B'Class object could have and have
+the compiler allocate the max size so that Object : B'Class could mute its tag.
+
+This is something we could investigate.
+
+Also Ada is used in many contexts that use dynamic allocation and it is fine to
+allow that
+
+>
+>> (d) Use Array indeces as we do in SPARK.
+>
+> ??? Is this supposed to be a joke? The smiley is missing.
+>
+
+sort of Using ideces instead of access types gets rid of a heck of a lot of
+problems here :)
+
+> I'd add (e):
+>
+> (e) Tell people that Ada is just fine as it is and they should use it
+> properly.
+
+Ada is not fine as is and you and I agree that things should be fixed. you made
+a very convincing point in your email.
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Wednesday, March 18, 2009  4:49 PM
+
+> Therefore, procedure P ought to properly be written as:
+>
+>    procedure P (XB : in out B);
+>
+> And .all passed when needed. (This has the appropriate side effect of
+> making the fact that XB cannot be null obvious, although at least you
+> can do that optionally in Ada 2005.)
+>
+> If you need an access of XB inside of the body of P, you can write
+> XB'Unchecked_Access.
+
+What about introducing a new pragma to tag the fact that inside P we will use a
+reference to XB and so we should pass it only objects whose lifetime is the
+sames as that of B, something like
+
+     procedure P (XB : in out B);
+     pragma Reference_To (XB); -- just using some random pragma name here
+
+and then inside P we could write
+
+     procedure P (XB : in out B) is
+     begin
+       ... XB'Access
+
+safely since the compiler could check that all calls to P are made with actuals
+whose lifetime is that of type B? We could even allow the romoval of .all so one
+could write
+
+    P (new B)
+
+or
+
+    type Any_B is access all B'Class;
+
+    AB : Any_B := new B;
+
+    AB.P; -- dispatching call
+
+that would allow us to never have to use anonymous access as parameters for
+primitive operations.
+
+Things are unfortunately a bit more complicated when we want to have a function
+returning a reference to an object of type B or B'Class.....
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 18, 2009  5:07 PM
+
+> What about introducing a new pragma to tag the fact that inside P we
+> will use a reference to XB and so we should pass it only objects whose
+> lifetime is the sames as that of B, something like
+>
+>      procedure P (XB : in out B);
+>      pragma Reference_To (XB); -- just using some random pragma name
+> here
+>
+> and then inside P we could write
+>
+>      procedure P (XB : in out B) is
+>      begin
+>        ... XB'Access
+>
+> safely since the compiler could check that all calls to P are made
+> with actuals whose lifetime is that of type B?
+
+That's an interesting idea. I wouldn't want to use that in Claw (because we
+really wanted to use local objects there), but I can imagine a number of places
+that it would help. Perhaps there is some way to include/associate that with my
+specified accessibility idea.
+
+It's interesting (but not that surprising) that most of the issues that dog
+anonymous access types also appear in "in out" parameters.
+
+> We could even allow the romoval of .all so one could write
+>
+>     P (new B)
+>
+> or
+>
+>     type Any_B is access all B'Class;
+>
+>     AB : Any_B := new B;
+>
+>     AB.P; -- dispatching call
+>
+> that would allow us to never have to use anonymous access as
+> parameters for primitive operations.
+
+That seems like going a bit too far for me.
+
+> Things are unfortunately a bit more complicated when we want to have a
+> function returning a reference to an object of type B or B'Class.....
+
+Well, if I get my pet idea, "in out" returns (which can only return writable
+existing objects), then the same approach could be applied there. And we've then
+wiped out the last need for explicit references in an O-O spec.
+
+But I have to admit that's asking a lot (even though it would make the
+containers much more usable).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 18, 2009  5:09 PM
+
+...
+> And SPARK has allowed tagged types since Issue 2.3 of the Reference
+> SPARK95 doc.
+
+The last time I asked about that, SPARK still didn't allow dispatching (or
+access-to-subprograms, which are equivalent). O-O without dispatching is like a
+three-legged stool with two legs. :-) You don't really need tagged types or
+'Class if you can't dispatch. Has that changed?
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Wednesday, March 18, 2009  5:16 PM
+
+That's still true.  SPARK allows type extension, but no use of class-wide types.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 18, 2009  6:15 PM
+
+> Without the below example, I would have no idea what you meant by "upcast".
+> I would have called them "downcast" since they are going toward the
+> root (and the roots of all [real] trees that I know of are on the bottom).
+
+All computer science folks draw trees upside-down, with the root at the top.
+"Down" the hierarchy is toward the leaves, "up" is toward the root. This is
+standard terminology in OO circles when talking about class/type hierarchies.
+Please don't try to make people say "toward the root" instead of "upcast" or
+"upward conversion".
+
+Upcasts are safe (T2'Class to T1'Class, where T2 is derived from T1).
+Downcasts are unsafe (T1'Class to T2'Class requires a run-time check).
+
+The basic problem that anon access was supposed to solve (and didn't) is to
+allow upcasts on pointers to be implicit (access-to-T2'Class implicitly
+converted to access-to-T1'Class).  I think this whole discussion has lost sight
+of that simple issue, and delved into endless complexity.  Sigh.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 18, 2009  7:14 PM
+
+> All computer science folks draw trees upside-down, with the root at
+> the top.
+> "Down" the hierarchy is toward the leaves, "up" is toward the root.
+> This is standard terminology in OO circles when talking about
+> class/type hierarchies.  Please don't try to make people say "toward
+> the root" instead of "upcast" or "upward conversion".
+
+I highly doubt that "all" computer science folks do anything in particular at
+all. This is just like stacks, sometimes people say they grow up, sometimes they
+grow down. Is it too much to ask for some clarity? I really wanted to understand
+exactly what is being asked, and not in some secret code.
+
+In any case, this is an Ada subgroup, and the only thing we can truly assume is
+that people know Ada terminology. (And even that is a stretch sometimes.) "cast"
+has nothing whatsoever to do with Ada, and directions are ambiguous. So, yes,
+please, say conversion toward the root, or give an example. (Even better, don't
+do any stupid conversions at all, they usually show a design problem. :-)
+
+> Upcasts are safe (T2'Class to T1'Class, where T2 is derived from T1).
+> Downcasts are unsafe (T1'Class to T2'Class requires a run-time check).
+>
+> The basic problem that anon access was supposed to solve (and
+> didn't) is to allow upcasts on pointers to be implicit
+> (access-to-T2'Class implicitly converted to access-to-T1'Class).  I
+> think this whole discussion has lost sight of that simple issue, and
+> delved into endless complexity.  Sigh.
+
+This is completely false. This discussion is pretty much the first time I've
+heard this described as an issue, and I don't recall *any* discussion that ever
+has talked about conversions solely in terms of anonymous access types. (That
+is, access conversions are defined in terms of what is legal on direct
+conversions.)
+
+Surely that was not the point of anonymous access types in Ada 95. (It didn't
+even allow conversions from access T to access T'Class: we added those in the
+Corrigendum.) And the only point I ever remember being discussed (other than
+some very hazy notion of generality) was about making limited with work better
+(as we couldn't figure out how to import an access type in a limited view). For
+that case, and ONLY that case, we were trying to avoid conversions.
+
+I really dislike someone who didn't even come to most of the meetings making
+silly claims about what problem some Ada 2005 feature was intended to solve. Or
+lecturing on "common CS practice". (It took me quite a while to calm down enough
+to be able to write a rational response.)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 18, 2009  7:55 PM
+
+> I really dislike someone who didn't even come to most of the meetings
+> making silly claims about what problem some Ada 2005 feature was intended to solve.
+> Or lecturing on "common CS practice". (It took me quite a while to
+> calm down enough to be able to write a rational response.)
+
+Randy, it's really not my intention to get you all riled up.
+I'm truly sorry to give offense!
+
+****************************************************************
+
+From: Dmitry A. Kazakov
+Sent: Thursday, March 19, 2009  3:39 AM
+
+>>     type B is tagged record ...
+>>     type Any_B is access all B'Class;
+>>
+>>     type D is new B with record ...
+>>     subtype Any_D is Any_B access D'Class;
+>
+> This is another option. The latter idea is interesting, although I'd
+> like a better explanation of the need.
+
+The issue is about whether a type Y based on some subtype S of the parent type T
+is a subtype of X based on T. Graphically:
+
+  T <--------- S
+  |              |
+  X <-- ? --- Y
+
+In the example S=D'Class, T=B'Class. X, Y are access types to them.
+
+This is the parallel types hierarchies problem. It is not only about access
+types. Consider arrays:
+
+   type T is new Integer;
+   type X is array (Positive range <>) of T;
+
+   subtype S is T range 1..20;
+   type Y is array (Positive range <>) of S;
+
+what is relation between X and Y?
+
+Very often, but not always Y is required to be a subtype of X.
+
+Ada has nothing to handle this.
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Thursday, March 19, 2009  9:17 PM
+
+you are absolutely right.
+
+it would be nice if we could write something like
+
+    subtype Y is X array (Positive range <>) of S;
+
+and if we even wanted to constrain the index something like
+
+
+    subtype Y is X array (10..20) of S;
+
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Thursday, March 19, 2009  9:35 AM
+
+> It's interesting (but not that surprising) that most of the issues
+> that dog anonymous access types also appear in "in out" parameters.
+>
+
+Let me go ver the things we could do to improve the situation
+
+First: Enhance general named access and ensure we do not need anonymous access.
+-------------------------------------------------------------------------------
+How:
+
+1/ generalize the notion of subtyping to all data types (see Dmitry email).
+    In the aces of named access types this would give
+
+       type B is tagged ...
+       type D is new B with ...
+
+       type Any_B is access all B'Class;
+       subtype any_D is any_B access all D'Class;
+
+2/ Ensure that we never need anonymous access for dispatching operations
+    and that we can safely take the 'access of a parameter. This time I'll
+    give you the version witout a pragma but with a new parameter mode:
+
+       procedure P (X : ref B; ....)
+
+    which means that X is a regular "in out" parameter for which you can safely
+    take the 'Access of X inside the body of P. This has imposes constraints
+    on the caller side (the accessibility level of the actual must be that of
+    type B). This allows to safely point to X'Access inside P.
+
+
+Second: Adjust Anonymous Access
+--------------------------------
+How:
+
+1/ Add Tuck's dynamic accessibility idea
+
+2/ Forbid anonymous allocators except for co-extensions
+    This add some incompatibility with Ada 95/2005 which has a simple
+    work around which I find to enhance readability. Specifically,
+    given
+
+      procedure P (XA : access B);
+
+    the following would be illegal
+
+      Ptr : access B := new B; --  illegal (Ada 2005 incompatibility)
+      P (new B);               --  illegal (Ada   95 incompatibility)
+
+    and one would have to write instead (note the equivalent semantics)
+
+      Obj : aliased B;
+      Ptr : access B := Obj'Access;
+
+      declare
+         Local_Obj : aliased B;
+      begin
+         P (Local_Obj'Access);
+      end;
+
+    which is in my opinion preferable since it makes the semantics clear
+    (I find it very confusing to use "new B" to allocate data other than in
+    the heap or a pol specific area).
+
+Note that anonymous allocators in co-extensions pose no problem since they get
+allocated in the same place as the englobing object and get automatically
+released when the englobing object is freed.
+
+By removing the two anonymous allocators above we are guaranteed that all
+allocations are done via a named access type of some sort in some heap/debug
+pool and can be freed accordingly.
+
+****************************************************************
+
+From: Quentin Ochem
+Sent: Thursday, March 19, 2009  9:38 AM
+
+> Could you explain why you need two different types to point at
+> objects that clearly belong to the same collection? That seems like a design
+> problem to me, but there may be a good reason that I'm missing.
+
+My problem is that I have to create a instance of a child of the root type, and
+then do some child-specific work on it, such as initialize fields, call new
+primitives, etc. E.g., in Franco's example:
+
+   type B is tagged record ...
+   procedure P1 (V : B);
+   type Any_B is access all B'Class;
+
+   type D is new B with record ...
+   procedure P2 (V : D);
+   type Any_D is access all D'Class;
+
+   then do, e.g.:
+
+   D_Ref : Any_D := new D;
+
+   D_Ref.P2;
+
+   Container.Add (Any_B (D_Ref));
+
+
+To me, the type Any_D is wrong - seems like it adds a new type but it's not how
+I want to use it - what I really want to say (and have no way currently in Ada)
+is to say that Any_D is of type Any_B but points to an object of type B'Class.
+Having some way of saying that Any_D is a subtype of Any_B with an additional
+constraint would solve the issue. Using e.g. Franco's suggestion:
+
+   type D is new B with record ...
+   subtype Any_D is Any_B access D'Class;
+
+or perhaps one step further, at object declaration:
+
+   D_Ref : Any_B access D'Class := new D;
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Thursday, March 19, 2009  10:21 AM
+
+I missed some things in my previous email so here is a revised set of ideas
+
+
+Enhancing general named access and ensure we do not need anonymous access.
+--------------------------------------------------------------------------
+How:
+
+1/ generalize the notion of subtyping to all data types (see Dmitry email).
+    In the aces of named access types this would give
+
+       type B is tagged ...
+       type D is new B with ...
+
+       type Any_B is access all B'Class;
+       subtype Any_D is any_B access all D'Class;
+
+    Note that this means that when we go from Any_B to Any_D we would have
+    a runtime check and would not need a type conversion.
+
+    Alternatively if we wanted to make things simple we could allow implicit
+    named access type conversions such as
+
+       type Any_B is access all B'Class;
+       type Any_D is access all D'Class;
+
+    D_Ref : Any_D;
+    B_Ref : Any_B := Any_D; --  implicit type conversion
+
+
+2/ Ensure that we never need anonymous access for dispatching operations
+    and that we can safely take the 'access of a parameter. This time I'll
+    give you the version without a pragma but with a new parameter mode:
+
+       procedure P (X : ref B; ....)
+
+    which means that X is a regular "in out" parameter for which you can safely
+    take the 'Access of X inside the body of P. This has imposes constraints
+    on the caller side (the accessibility level of the actual must be that of
+    type B). This allows to safely point to X by using X'Access inside P.
+
+
+3/ Allow the use of named general access types when creating circular data
+    types in two different packages in the presence of limitred with:
+
+       limited with P2;
+       package P1 is
+          type Access_Q is access all Q;
+          type Q is record
+             AR : P2.Access_R;
+             ...
+
+       limited with P1;
+       package P2 is
+          type Access_R is access all R;
+          type R is record
+             AQ : P1.Access_Q;
+             ...
+
+4/ Allow "in out" for functions (anonymous access are used today to work-around
+    this restriction which is a shame, we could just allow "in out" for
+    functions.
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Thursday, March 19, 2009  10:27 AM
+
+Adjusting Anonymous Access
+--------------------------------
+This is a bit of a radical set of ideas so take it with a grain of salt :)
+
+1/ Make the accessibility level of anonymous "access T" static and be
+    that of T (all accessibility checks are now static)
+
+2/ Allow anonymous allocators. They would be allocated from a pool associated
+    with T and would have static accessibility (that of T).
+
+3/ Allow "in out" as a parameter mode for anonymous access
+
+4/ Have a T'Free procedure to de-allocate objects allocated with anonymous
+    allocators
+
+****************************************************************
+
+From: Dmitry A. Kazakov
+Sent: Thursday, March 19, 2009  2:49 PM
+
+> it would be nice if we could write something like
+>
+>     subtype Y is X array (Positive range <>) of S;
+>
+> and if we even wanted to constrain the index something like
+>
+>     subtype Y is X array (10..20) of S;
+
+The solution should be universal rather than access or array type specific.
+It is about propagation of the type constraint.
+
+Let you have some type X defined by an algebraic type operation f
+
+   X = f (T1, T2, ... Tn)
+
+Here f is a operation that takes types as arguments and produces a new type,
+such as "is access T", "is array (T1) of T2", "is record T1, T2, ..., Tn", "is
+new T" etc.
+
+Then, putting a constraint on any of Ti should produce a corresponding
+constrained subtype of X.
+
+One possible way is to allow discriminatns everywhere, and provide mapping of
+various existing constraints (like array bounds, numeric ranges, access type
+pools, tag of a class-wide type) to the corresponding discriminants. So that you
+could declare:
+
+   type X (L, U : Integer) is array (Integer range L..U) of Float;
+
+then
+
+   subtype Y is X (L => 0);  -- Index is positive
+
+Your case with access types:
+
+   type Any_T (Parent : T'Class''Tag) is access all T'Class (Parent);
+   subtype Any_S is Any_T (Parent => S''Tag);
+
+Note that "not null", "all", "constant" are all constraints of access types.
+There would be no need to wire them into fixed constructs if they considered as
+such from the beginning.
+
+In short, it would greatly simplify and unify the language, which obviously will
+never happen. (:-()
+
+****************************************************************
+
+From: Franco Gasperoni
+Sent: Friday, March 20, 2009  11:40 AM
+
+> One possible way is to allow discriminatns everywhere,
+
+
+There is a simpler solution which is
+
+   subtype <identifier> is [null_exclusion] <subtype_mark> <type_definition>
+
+and then it's just a matter of checking that <type_definition> is a "subset" of
+the type definition of the <subtype_mark>.
+
+****************************************************************
+
+From: Dmitry A. Kazakov
+Sent: Friday, March 20, 2009  12:30 PM
+
+This is a far more complex solution if workable at all. If I correctly
+understood your proposal it would require structural types matching which
+firstly not Ada and secondly undecidable.
+
+****************************************************************
+
+From: Simon Wright
+Sent: Friday, March 20, 2009  1:36 AM
+
+...
+>  then do, e.g.:
+>
+>  D_Ref : Any_D := new D;
+>
+>  D_Ref.P2;
+>
+>  Container.Add (Any_B (D_Ref));
+
+D_Ref : Any_B := new D;
+My_D : D renames D (D_Ref.all);  -- runtime check here would be pointless (in context!)
+
+My_D.P2;
+
+****************************************************************
+
+From: Quentin Ochem
+Sent: Sunday, March 22, 2009  7:13 PM
+
+That's indeed an other option - still, it feels wrong to have two operations to
+do (declaration + conversion, or declaration + renaming) for this simple thing.
+No other language that I know of requires such machinery. It's particularly
+frustrating when using a lot of OOP - and have to write these things all around
+the place which really doesn't improve readability or safety.
+
+Anyway - just my 2 cents.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent