CVS difference for ai12s/ai12-0215-1.txt

Differences between 1.2 and version 1.3
Log of other versions for file ai12s/ai12-0215-1.txt

--- ai12s/ai12-0215-1.txt	2017/01/14 02:55:52	1.2
+++ ai12s/ai12-0215-1.txt	2017/04/21 05:26:33	1.3
@@ -76,7 +76,7 @@
 
 !discussion
 
-This proposal is purely syntactic sugar which allows eliminating the 
+This proposal is purely syntactic sugar which allows eliminating the
 instance declaration for instances that are only used to declare a single
 group of objects.
 
@@ -511,7 +511,7 @@
 > I would very much
 > like to see instantiation of
 > (stateless) generics as part of declaring an object.  E.g:
-> 
+>
 >     X : Vectors.Vector(Integer);
 
 I've written up a basic proposal for this feature as purely syntactic sugar.
@@ -560,16 +560,16 @@
 From: Tucker Taft
 Sent: Monday, January 9, 2017  9:07 PM
 
-> I purposely did not address any structural equivalence ideas in this 
-> proposal. While I remain open to further examples on this point, I am 
-> absolutely not interested in tying any important new functionality to 
+> I purposely did not address any structural equivalence ideas in this
+> proposal. While I remain open to further examples on this point, I am
+> absolutely not interested in tying any important new functionality to
 > anonymous declarations (be them new or old functionality).
 >
-> We almost always come to regret tying one new feature with some other 
-> new feature. (Bob has said this better than I several times in the 
-> past.) I definitely don't want to see people writing generic units 
-> just so that they can get structural type equivalence, nor do I want 
-> to see people writing anonymous instances just for this purpose when 
+> We almost always come to regret tying one new feature with some other
+> new feature. (Bob has said this better than I several times in the
+> past.) I definitely don't want to see people writing generic units
+> just so that they can get structural type equivalence, nor do I want
+> to see people writing anonymous instances just for this purpose when
 > otherwise a normal declaration would do.
 
 When I said "structural equivalence" what I meant was that two instantiation
@@ -577,7 +577,7 @@
 instantiation.  So there is only one type, and only one instance, which is
 being used in all places where the short-hand specifies the same parameters.
 This is important so as to avoid code bloat, and is generally what you want
-when using this sort of short-hand for generic instantiation. 
+when using this sort of short-hand for generic instantiation.
 
 This implies there should be no state associated with the generic, or else
 you can unintentionally create race conditions, etc.
@@ -588,7 +588,7 @@
 very few Ada compilers implement generic sharing, this feature is of much
 more limited use if it produces extraordinary code bloat.
 
-> Anonymous anything should NEVER have capabilities that the otherwise 
+> Anonymous anything should NEVER have capabilities that the otherwise
 > equivalent named entity do not have.
 
 I am not proposing that.  I am merely proposing that the syntactic sugar
@@ -600,17 +600,17 @@
 From: Randy Brukardt
 Sent: Monday, January 9, 2017  11:13 PM
 
-> When I said "structural equivalence" what I meant was that two 
-> instantiation short-hands with the same parameters would refer to the 
+> When I said "structural equivalence" what I meant was that two
+> instantiation short-hands with the same parameters would refer to the
 > same implicit instantiation.
 
 Raphael was talking about something more general in his messages, and that's
 mainly what I responded to. But...
 
 > ...  So there is only
-> one type, and only one instance, which is being used in all places 
+> one type, and only one instance, which is being used in all places
 > where the short-hand specifies the same parameters.
-> This is important so as to avoid code bloat, and is generally what you 
+> This is important so as to avoid code bloat, and is generally what you
 > want when using this sort of short-hand for generic instantiation.
 
 I stand by my statement: I don't want special semantics just for anonymous
@@ -634,7 +634,7 @@
 when this is and is not done, plus the nesting implications. Sounds like a
 lot of work.
 
-> This implies there should be no state associated with the generic, or 
+> This implies there should be no state associated with the generic, or
 > else you can unintentionally create race conditions, etc.
 
 Which is another reason that some sort of implicit instance sharing is a bad
@@ -642,10 +642,10 @@
 
 If we do this at all, let it be exactly syntactic sugar, with no semantic
 changes.
- 
-> If we believe it is important to allow implicit instantiations of 
-> state-ful generics (something about which I am not personally 
-> convinced), then I would propose we define an aspect to distinguish 
+
+> If we believe it is important to allow implicit instantiations of
+> state-ful generics (something about which I am not personally
+> convinced), then I would propose we define an aspect to distinguish
 > the two approaches.
 
 It's hard to write a useful generic that doesn't have some sort of state.
@@ -668,7 +668,7 @@
 allowed with Tucker's scheme.]
 
 > Given that very
-> few Ada compilers implement generic sharing, this feature is of much 
+> few Ada compilers implement generic sharing, this feature is of much
 > more limited use if it produces extraordinary code bloat.
 
 That's only a problem if someone is used extraordinary numbers of instances.
@@ -676,11 +676,11 @@
 cases. Moreover, it only works if the instances actually can be hoisted (that
 depends on where the actual parameters are declared, as I previously noted).
 
-> > Anonymous anything should NEVER have capabilities that the otherwise 
+> > Anonymous anything should NEVER have capabilities that the otherwise
 > > equivalent named entity do not have.
-> 
-> I am not proposing that.  I am merely proposing that the syntactic 
-> sugar involves a more globally instantiated generic, rather than a new 
+>
+> I am not proposing that.  I am merely proposing that the syntactic
+> sugar involves a more globally instantiated generic, rather than a new
 > one instantiated at each point of use.
 
 Yes you are. You're adding a poor-man's sharing mechanism, and only allowing
@@ -702,10 +702,10 @@
 It strikes me that many new proposals are just about ease of writing... Sigh
 
 
-> When I said "structural equivalence" what I meant was that two 
-> instantiation short-hands with the same parameters would refer to the 
-> same implicit instantiation.  So there is only one type, and only one 
-> instance, which is being used in all places where the short-hand 
+> When I said "structural equivalence" what I meant was that two
+> instantiation short-hands with the same parameters would refer to the
+> same implicit instantiation.  So there is only one type, and only one
+> instance, which is being used in all places where the short-hand
 > specifies the same parameters.
 
 Even if the two implicit instantiations are within different compilation
@@ -716,18 +716,18 @@
 From: Randy Brukardt
 Sent: Tuesday, January 10, 2017  12:04 AM
 
-> It strikes me that many new proposals are just about ease of 
+> It strikes me that many new proposals are just about ease of
 > writing... Sigh
 
 At least most such proposals have a "low" priority.
- 
+
 ...
-> > When I said "structural equivalence" what I meant was that two 
-> > instantiation short-hands with the same parameters would refer to 
-> > the same implicit instantiation.  So there is only one type, and 
-> > only one instance, which is being used in all places where the 
+> > When I said "structural equivalence" what I meant was that two
+> > instantiation short-hands with the same parameters would refer to
+> > the same implicit instantiation.  So there is only one type, and
+> > only one instance, which is being used in all places where the
 > > short-hand specifies the same parameters.
-> Even if the two implicit instantiations are within different 
+> Even if the two implicit instantiations are within different
 > compilation units?
 
 Yes, I wondered that too. If it is only within one program unit, it would
@@ -738,6 +738,1712 @@
 people have learned from using other compilers, but I think a lot of it is
 natural. (Especially if we're only talking about container-like generics, as
 in this proposal.)
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Tuesday, January 10, 2017  12:17 AM
+
+I'm afraid that it would end up with something like: shared within a program
+unit, but duplicated across different program units... which is a sure
+recipe for disaster.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, January 10, 2017  7:10 AM
+
+>> When I said "structural equivalence" what I meant was that two
+>> instantiation short-hands with the same parameters would refer to the
+>> same implicit instantiation.  So there is only one type, and only one
+>> instance, which is being used in all places where the short-hand
+>> specifies the same parameters.
+> Even if the two implicit instantiations are within different
+> compilation units?
+
+Yes, it would be independent of where the instantiation occurred, so long as
+the actuals match.  Note that we already have a pretty good definition of what
+it means for generic actuals to match, thanks to the definition of formal
+packages.
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Tuesday, January 10, 2017  7:36 AM
+
+But where would the instantiation reside?
+
+i.e. if there is a first instantiation deep in a sub-sub-procedure inside a
+package body, how can it be shared with an instantiation in a different
+library package? What happens if the first one is recompiled (without the
+instantiation)? Does it create dependences between unrelated package bodies?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, January 10, 2017   9:13 AM
+
+This problem is faced by all languages that share generic instantiations based
+on their actuals, including Dec Ada at one point, I believe (RR Ada does
+universal sharing, so you just compile the generic body once).
+
+The instantiations are given a unique name based on their actuals.  The code
+is then generated into a separate file, one per instantiation, or is put into
+something like "common block" sections such that the linker only pulls in one
+of them.  In the C++ world, these two approaches are called the "Cfront" model
+and the "Borland" model, for historical reasons.  Since most linkers now
+support the ability to pull in just one copy of a same-named
+"linkonce"/"comdat" section from multiple object modules, the "Borland" model
+is used more frequently now.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, January 10, 2017   4:25 PM
+
+In this model, where is the instance elaborated? (This matters for all
+instances, as at least the formals need to be evaluated.) How you do deal with
+actual parameters that are local to some subprogram if the instance is
+elaborated at the library level?
+
+It seems to me that this cannot be used as a general technique in Ada; one has
+to limit its applicability both based on the actual parameters and on the
+characteristics of the body (as you say, this only works sanely if there is no
+state). As such, this seems like a fine implementation technique.
+
+But I fail to see why it is a good idea to tie this technique solely to
+anonymous instances, as opposed to using it for all qualified instances.
+(After all, sharing implementations is a reasonable as-if optimization.) You
+don't want to be putting bizarre restrictions on anonymous instances (such as
+no local types or subprograms). And there's no need to make the instance work
+differently than if it was explicitly declared at the same place (there's no
+need to make the sharing visible to the programmer).
+
+So I could see encouraging this sort of implementation somehow, but not
+changing any semantics to in effect force it. (The language has nothing to say
+about code size of implementations anyway, else some sort of generic sharing
+would have been mandated decades ago.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, January 10, 2017   5:14 PM
+
+> In this model, where is the instance elaborated? (This matters for all
+> instances, as at least the formals need to be evaluated.) How you do
+> deal with actual parameters that are local to some subprogram if the
+> instance is elaborated at the library level?
+
+You can't share at a level any more global than the actuals.  So that case is
+simpler, since everything ends up as nested within the subprogram.
+
+For library-level instantiations, the elaboration happens at the library
+level. This is similar to asking when package System is elaborated when a use
+of 'Address appears.  It is elaborated before any reference.
+
+> It seems to me that this cannot be used as a general technique in Ada;
+> one has to limit its applicability both based on the actual parameters
+> and on the characteristics of the body (as you say, this only works
+> sanely if there is no state). As such, this seems like a fine
+> implementation technique.
+
+I guess I don't understand your point.  We want these to be semantically all
+the same instance, declaring only a single type, a single set of exceptions,
+etc. That is clearly visible at the semantic level, so you can't just sweep
+this under the implementation-technique "rug." I believe the formal package
+rules for matching given in RM 12.7(5.3-8) are probably adequate to determine
+if two "short-hands" are referring to the same instance.
+
+> But I fail to see why it is a good idea to tie this technique solely
+> to anonymous instances, as opposed to using it for all qualified instances.
+> (After all, sharing implementations is a reasonable as-if
+> optimization.) You don't want to be putting bizarre restrictions on
+> anonymous instances (such as no local types or subprograms). And
+> there's no need to make the instance work differently than if it was
+> explicitly declared at the same place (there's no need to make the sharing
+> visible to the programmer).
+
+Here is where we disagree. The point is that "Vectors.Vector(Integer)" is a
+single type, interchangeable with all other "Vectors.Vector(Integer)" since
+they all refer to the same unique instance.
+
+> So I could see encouraging this sort of implementation somehow, but
+> not changing any semantics to in effect force it. (The language has
+> nothing to say about code size of implementations anyway, else some
+> sort of generic sharing would have been mandated decades ago.)
+
+I think you are missing my fundamental point here.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, January 10, 2017  5:49 PM
+
+...
+> You can't share at a level any more global than the actuals.
+> So that case is simpler, since everything ends up as nested within the
+> subprogram.
+
+In other words, even more complication (how the declaration is processed
+depends on the actuals). Yuck.
+
+> For library-level instantiations, the elaboration happens at the
+> library level.  This is similar to asking when package System is
+> elaborated when a use of 'Address appears.  It is elaborated before
+> any reference.
+>
+> > It seems to me that this cannot be used as a general technique in
+> > Ada; one has to limit its applicability both based on the actual
+> > parameters and on the characteristics of the body (as you say, this
+> > only works sanely if there is no state). As such, this seems like a
+> > fine implementation technique.
+>
+> I guess I don't understand your point.  We want these to be
+> semantically all the same instance, declaring only a single type, a
+> single set of exceptions, etc. That is clearly visible at the semantic
+> level, so you can't just sweep this under the implementation-technique
+> "rug."
+
+True, but why do you want this? It doesn't seem necessary for the motivating
+usage of the feature: to replace an anonymous array declaration by a vector
+container.
+
+That is, if I have:
+
+    Buf1 : array (1..MAX_BUF) of Some_Record;
+    Buf2 : array (1..MAX_BUF) of Some_Record;
+
+the fact that these are different types is a non-issue. (I have lots of
+declarations like this in my code.) If I wanted these to be unbounded vectors
+instead:
+
+    Buf1 : Ada.Containers.Vectors.Vector (Natural, Some_Record);
+    Buf2 : Ada.Containers.Vectors.Vector (Natural, Some_Record);
+
+The same would be true: the fact that these are different types doesn't
+matter.
+
+More generally, one might use an anonymous type in a scenario where operations
+on the entire type (object) are not anticipated. I would expect the same to be
+true here (if you need to pass Buf1 to some other generic, or to interassign
+these, it's better that the instance has a first-class name). [Aside: The
+proposal I made does not actually require a named instance to do that, in that
+sense it is better than an anonymous array -- if you just need a type name in
+some single place, you can get it without introducing another name.]
+
+And if there IS a good reason to support structural equivalence in some cases
+(as Raphael argued in the original thread), one surely does not want to force
+people to use anonymous instances to get it (which could force people to use
+generics in cases where they are not needed).
+
+> I believe the
+> formal package rules for matching given in RM 12.7(5.3-8) are probably
+> adequate to determine if two "short-hands" are referring to the same
+> instance.
+>
+> > But I fail to see why it is a good idea to tie this technique solely
+> > to anonymous instances, as opposed to using it for all qualified instances.
+> > (After all, sharing implementations is a reasonable as-if
+> > optimization.) You don't want to be putting bizarre restrictions on
+> > anonymous instances (such as no local types or subprograms). And
+> > there's no need to make the instance work differently than if it was
+> > explicitly declared at the same place (there's no need to make the
+> > sharing visible to the programmer).
+>
+> Here is where we disagree.  The point is that
+> "Vectors.Vector(Integer)" is a single type, interchangeable with all
+> other "Vectors.Vector(Integer)" since they all refer to the same
+> unique instance.
+
+Again, why is that a good thing? It seems to damage the Ada type model for no
+reason (all other anonymous types are distinct, after all).
+
+> > So I could see encouraging this sort of implementation somehow, but
+> > not changing any semantics to in effect force it. (The language has
+> > nothing to say about code size of implementations anyway, else some
+> > sort of generic sharing would have been mandated decades ago.)
+>
+> I think you are missing my fundamental point here.
+
+You want to adopt an unnecessarily complex semantics here so you can convince
+your employer to implement an optimization that arguably they should implement
+anyway? :-)
+
+I don't think I missed it, I just see no justification for it whatsoever. Thus
+I'm ignoring it, since it isn't fundamental to the description or usage of
+this shorthand.
+
+You'll need to explain why this is valuable semantics for these instances.
+[And in the abstract, not reasons that have nothing to do with the Standard
+like "code bloat" - implementations have plenty of ways to avoid "code bloat"
+for instances should they care to use them; it's not our job to try to force
+implementation techniques.]
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, January 10, 2017  11:03 PM
+
+>> ... I think you are missing my fundamental point here.
+>
+> You want to adopt an unnecessarily complex semantics here so you can
+> convince your employer to implement an optimization that arguably they
+> should implement anyway? :-)
+
+It seems we aren't on the same wavelength here.
+
+> I don't think I missed it, I just see no justification for it whatsoever.
+> Thus I'm ignoring it, since it isn't fundamental to the description or
+> usage of this shorthand.
+
+Well, presume you define a non-generic operation that takes a
+Vectors.Vector(My_Integer) as a parameter.  That seems like a pretty normal
+thing to do, and I would like to pass it any object declared as
+"Vectors.Vector(My_Integer)."  That seems pretty fundamental to me.
+
+> You'll need to explain why this is valuable semantics for these instances. ...
+
+This seems like a fundamental capability once you have a type constructor like
+this which you could use to declare the type of a formal parameter, so I am
+surprised you see it as unimportant.
+
+****************************************************************
+
+From: Raphael Amiard
+Sent: Wednesday, January 11, 2017  4:15 AM
+
+>> You want to adopt an unnecessarily complex semantics here so you can
+>> convince your employer to implement an optimization that arguably
+>> they should implement anyway? :-)
+>
+> It seems we aren't on the same wavelength here.
+
+Yes, Randy, structural generic equality is not about code size optimization
+IMHO, it's about modularity.
+
+If you have the following code in library 1, from vendor A:
+
+procedure Frobulize (Vec : Vectors.Vector (Natural, Integer));
+
+And the following code in library 2, from vendor B:
+
+function Create_Sequence return Vectors.Vector (Natural, Integer);
+
+You want to be able to use those two subprograms together seamlessly,
+without using conversion functions.
+
+This is already a problem, and a missing feature, without inline generic
+types. However, this gets much worse if you allow inline generic types,
+because with the code above, you intuitively expect those two inline types
+to be compatible, and will cause much hair pulling if you break that
+intuition.
+
+Regarding your point:
+
+> I purposely did not address any structural equivalence ideas in this
+> proposal. While I remain open to further examples on this point, I am
+> absolutely not interested in tying any important new functionality to
+> anonymous declarations (be them new or old functionality).
+
+I have no strong opinion on that. I agree that having a structural equivalence
+feature that is in some way orthogonal would be good, and would allow users to
+benefit from the semantic benefits without using the inline notation.
+
+However, I don't think that inline types with nominal semantics rather than
+structural make any sense at all, for the reasons outlined above, so I would
+still argue that structural equivalence should be the default rules in the
+case of inline types.
+
+Tucker, I think we have the same underlying idea, but please expand/correct me
+there if I'm mistaken.
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, January 11, 2017  5:09 AM
+
+> If you have the following code in library 1, from vendor A:
+>
+> procedure Frobulize (Vec : Vectors.Vector (Natural, Integer));
+>
+> And the following code in library 2, from vendor B:
+>
+> function Create_Sequence return Vectors.Vector (Natural, Integer);
+>
+> You want to be able to use those two subprograms together seamlessly,
+> without using conversion functions.
+
+Sorry, but I don't accept this example, because it is very bad Ada to have
+vectors of Integer indexed by Integer. What do they represent?
+
+Ada is about STRONG TYPING. Never use Integer. Use types that model problem
+space. Do you think that two different vendors will need vectors of -say-
+Length, without having some common package where this abstraction is defined?
+And shouldn't this abstraction (explicitely) instantiate vectors of Length if
+needed?
+
+Side note: I'm a bit hot on this topic, because I just finished an expertise
+where the only types they used were Integer and Boolean. Not even Positive
+when indexing strings! The result is an horrible mess, where they gained
+nothing from writing in Ada.
+
+I am not interested in features that help people write bad Ada.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 11, 2017   7:14 AM
+
+> Ada is about STRONG TYPING. Never use Integer. Use types that model
+> problem space. Do you think that two different vendors will need
+> vectors of -say- Length, without having some common package where this
+> abstraction is defined? And shouldn't this abstraction (explicitely)
+> instantiate vectors of Length if needed?
+
+Fair enough.  Presume we have an example like
+
+    procedure Print_Recs (Patients : Vectors.Vector(Patient_ID, Patient_Rec));
+
+> Side note: I'm a bit hot on this topic, because I just finished an
+> expertise where the only types they used were Integer and Boolean. Not
+> even Positive when indexing strings! The result is an horrible mess,
+> where they gained nothing from writing in Ada.
+>
+> I am not interested in features that help people write bad Ada.
+
+Fine.  I don't see this as affecting whether or not people use "Integer"
+rather than "Patient_ID"
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, January 11, 2017  8:27 AM
+
+> Fair enough.  Presume we have an example like
+>
+>    procedure Print_Recs (Patients : Vectors.Vector(Patient_ID, Patient_Rec));
+
+Well, I would expect Patient_ID and Patient_Rec to be declared in some
+package, and if there is a need to maintain lists of patients, there would
+certainly be an explicit instantiation of Vectors. Or even better,
+operations to manipulate lists of Patients, with Vectors buried in the body.
+I see no need for implicit instantiations here.
+
+>> I am not interested in features that help people write bad Ada.
+>>
+> Fine.  I don't see this as affecting whether or not people use "Integer"
+> rather than "Patient_ID"
+
+I have a (not scientifically supported) feeling that people who structure
+their code correctly, with appropriate abstract data types, don't need these
+implicit instantiations. Only those who program computers* with Integer and
+Boolean need this.
+
+* I keep saying in my courses: "stop programming computers! Design software
+  applications".
+
+****************************************************************
+
+From: Tullio Vardanega
+Sent: Wednesday, January 11, 2017  8:34 AM
+
+I think JP has a point here, which may well severely contrast with the
+implementors' wish of being able to "digest", without too much pain, user
+code that might have been written differently for the better.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 11, 2017  8:58 AM
+
+Finding the "right" place to put these instantiations can be a challenge.
+What generally happens is you end up with several, because you have relatively
+independent packages that both want to take a "Vector(Blah)."  We have had
+heartache in the past over trying to decide where to declare "type String_Ptr
+is access String;".  Similar examples might be "Set(Character)" or packed
+array of Boolean.
+
+Once you start programming regularly with Sets, Maps, Vectors, etc., it can be
+a royal pain to always have to figure out where to put the instantiations.  In
+my experience, most of us haven't reached that point, but after programming a
+lot in ParaSail, where Sets, Maps, Vectors, etc., are pretty much all you use,
+I can't imagine having to figure out where I would have to put all the various
+instantiations, if they were explicit.
+
+Sometimes I do create a short-hand using something like "type Sym_Info_Map is
+Map<Symbol, Info>" or equivalent, which is easy to do, but many other times
+there is no natural place to put that, and in any case, these are just short
+hands (equivalent to subtype declarations in Ada).
+
+Ada's need for explicit instantiations is one of the most obvious places (to
+me) where Ada feels heavier weight than other languages.  I really don't think
+this is enhancing the quality of Ada programs.  It just feels more like a
+"hoop" you have to jump through, and sometimes it creates dependences between
+compilation units that really don't belong there.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 11, 2017  2:02 PM
+
+...
+> Yes, Randy, structural generic equality is not about code size
+> optimization IMHO, it's about modularity.
+>
+> If you have the following code in library 1, from vendor A:
+>
+> procedure Frobulize (Vec : Vectors.Vector (Natural, Integer));
+
+Ada only allows subtype_marks in profiles, and that restriction exists for
+semantic reasons having to do with conformance and elaboration -- it is not
+some sort of methodological restriction.
+
+I can't imagine changing that, but even if we were going to change it, it
+ought to be generally applied and not tied to just this wacky construct.
+
+So you're worrying about something that is very unlikely to be ever part of
+the Ada model.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 11, 2017  2:58 PM
+
+...
+> It seems we aren't on the same wavelength here.
+>
+> > I don't think I missed it, I just see no justification for it whatsoever.
+> > Thus I'm ignoring it, since it isn't fundamental to the description
+> > or usage of this shorthand.
+>
+> Well, presume you define a non-generic operation that takes a
+> Vectors.Vector(My_Integer) as a parameter.  That seems like a pretty
+> normal thing to do, and I would like to pass it any object declared as
+> "Vectors.Vector(My_Integer)."  That seems pretty fundamental to me.
+
+I view this as an analog of the anonymous array type. So let's try the above
+statement replacing the new construct with the anonymous array type "array
+(1..Max) of Rec":
+
+  Well, presume you define a non-generic operation that takes a
+  "array (1..Max) of Rec" as a parameter.  That seems like a
+  pretty normal thing to do, and I would like to pass it any
+  object declared as ""array (1..Max) of Rec".  That seems
+  pretty fundamental to me.
+
+And that seems like a pretty silly statement to me, since it has never been
+true in Ada and clearly the world has not fallen in. So it can't be *that*
+fundamental.
+
+Indeed, neither of these constructs (anonymous array or anonymous instance)
+would ever be allowed in a parameter profile in Ada (as I mentioned to
+Raphael), so this is a complete non-concern.
+
+> > You'll need to explain why this is valuable semantics for these
+instances. ...
+>
+> This seems like a fundamental capability once you have a type constructor
+> like this which you could use to declare the type of a formal parameter, so
+> I am surprised you see it as unimportant.
+
+I've been privately criticized for making absolutist statements here, but I
+think I have no choice in this case, so one is about to appear:
+
+I've always regretted my part in the expansion of anonymous access types in
+Ada 2005. They proved complex to implement, make code harder to understand
+(both for humans and programs), and with one exception, add no capability.
+[That one exception should have been provided some other way, as I outlined
+in another message.] Several other ARG members (and members of the general
+public as well) have expressed similar sentiments to me; this is not a unique
+opinion.
+
+The old saying is "fool me once, shame on you; fool me twice, shame on me".
+I do not intend to bring shame onto me. As such, I would need the most
+compelling arguments possible (essentially, that no other way could possibly
+work) before I would sanction any further expansion to the use of anonymous
+types in subprogram parameters. That's ANY kind of anonymous types in
+parameter profiles.
+
+So I'd rather not waste any more time worrying about things that are not going
+to be part of any future Ada so long as I'm around.
+
+-------
+
+Let's switch to the positive.
+
+I recognize the value of the anonymous array declaration; I use it
+periodically to avoid having to invent names for types that are only going to
+be used once.
+
+Therefore, I can see the value of a similar construct to be used for
+containers. It would therefore have similar restrictions in use (thus, it
+only can appear in a stand-alone object declaration), and it creates a new
+type for each use. That's the proposal I outlined in the draft AI that I
+posted.
+
+I can believe that it could use some polishing, but I'm not willing to go
+significantly further than that. (I could see some use to an easier way to
+describe generic formal parameters of "any" vector type, for instance -- one
+can do that with formal packages, but it is clunky).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 11, 2017   3:11 PM
+
+...
+> Once you start programming regularly with Sets, Maps, Vectors, etc.,
+> it can be a royal pain to always have to figure out where to put the
+> instantiations.  In my experience, most of us haven't reached that
+> point, but after programming a lot in ParaSail, where Sets, Maps,
+> Vectors, etc., are pretty much all you use, I can't imagine having to
+> figure out where I would have to put all the various instantiations,
+> if they were explicit.
+
+Again, let's think of this statement using "arrays" in place of the
+containers:
+
+   Once you start programming regularly with arrays, it can be a royal pain
+   to always have to figure out where to put the array type declarations.
+   In my  experience, most of us haven't reached that point, but after
+   programming a lot in <Fortran??>), where arrays are pretty much all you
+   use, I can't imagine having to figure out where I would have to put all
+   the various type declarations, if they were explicit.
+
+This probably is a true statement, but it just reflects the basic problem of
+programming in Ada (any version of Ada): it's a pain to figure out where to
+declare things sometimes. That usually is a symptom of too little abstraction,
+but we all fall prey to it from time-to-time (abstraction being hard and
+time-consuming -- and usually very rewarding down the line).
+
+Which means that this is nothing new in any sense, and somehow attributing it
+to containers (or solving it *only* for containers) is really a mistake.
+If one was to solve this at all, one would have to solve it for all kinds of
+composite types (array, strings, containers, etc.) -- and one would also have
+to be quite certain that the solution isn't worse than the problem (as
+happened with anonynous access types).
+
+I'd be interested in seeing ideas in this area, but please let's not attribute
+an age-old Ada programming problem to just a single newish feature.
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, January 11, 2017  3:40 PM
+
+> I recognize the value of the anonymous array declaration; I use it
+> periodically to avoid having to invent names for types that are only
+> going to be used once.
+
+Not having to invent names is not a very good justification... But there is
+(IMHO) at least one major value to anonymous types: you know it is a
+singleton, that it's the only object of its kind, and this can be a useful
+information (especially for single tasks) that you want enforced by the
+compiler...
+
+... and that would be immediately broken with structural equivalence!
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, January 11, 2017  5:04 PM
+
+> ... As such, I would need the most
+> compelling arguments possible (essentially, that no other way could
+> possibly
+> work) before I would sanction any further expansion to the use of
+> anonymous types in subprogram parameters. That's ANY kind of anonymous
+> types in parameter profiles.
+>
+> So I'd rather not waste any more time worrying about things that are
+> not going to be part of any future Ada so long as I'm around.
+
+I think we have reached the "nub" of the question.  Do we think it is important
+to allow type "constructors" in formal parameter specifications?  That is,
+should the programmer be allowed to declare a procedure that takes a
+Vector(My_Integer) or must they always declare a type (perhaps as a side-effect
+of an explicit instantiation)?  I would agree that our experience with anonymous
+access types has been less than uniformly positive, though I could argue that
+allowing them for stand-alone objects is when things went south, and that is
+something which I (amazingly! ;-) did not support originally.  Using them for
+parameters was important in my view, and I still find the need for them
+regularly (unlike stand-alone objects of an anonymous access type, which I don't
+believe I have ever used).
+
+It is true that Ada never allowed an anonymous array type as a parameter type,
+while allowing it for stand-alone objects.  I would think there are still
+arguments on both sides of this decision (I think we know where you stand), and
+I guess I am convinced that we should be consistent -- if we think it is
+important to allow "Vector(Positive, My_Rec)" as a formal parameter subtype,
+then we should similarly allow "array(Positive range <>) of My_Rec".  I think it
+would be worth debating this issue in an ARG meeting, because e-mail does not
+provide a good decision process.
+
+The next question would be should we allow implicit instantiations as part of a
+type declaration?  E.g.:
+
+    "type Vec_Rec is new Vectors.Vector(Positive, My_Rec);"
+
+Here the array type provides a clearer model, that yes, if we allow it for a
+stand-alone object declaration, we should allow it in a type declaration.
+
+This at least allows us to eliminate one level of explicit instantiation.
+
+So perhaps we can agree on some of this, and we can leave the debate about the
+implicit instantiation as part of a formal parameter specification for an ARG
+meeting (perhaps over a few beers...).  Along with perhaps the discussion of
+whether implicit instantations should be permitted for "state-ful" generic
+packages, and maybe explicit type conversion rules. ;-)
+
+> ... (I could see some use to an easier way to describe generic formal
+> parameters of "any" vector type, for instance -- one can do that with
+> formal packages, but it is clunky).
+
+I agree, that is clearly of value, and much more pleasant than the complexities
+of formal packages.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 11, 2017  6:13 PM
+
+> I think we have reached the "nub" of the question.  Do we think it is
+> important to allow type "constructors" in formal parameter
+> specifications?  That is, should the programmer be allowed to declare
+> a procedure that takes a
+> Vector(My_Integer) or must they always declare a type (perhaps as a
+> side-effect of an explicit instantiation)?  I would agree that our
+> experience with anonymous access types has been less than uniformly
+> positive, though I could argue that allowing them for stand-alone
+> objects is when things went south, and that is something which I
+> (amazingly! ;-) did not support originally.  Using them for parameters
+> was important in my view, and I still find the need for them regularly
+> (unlike stand-alone objects of an anonymous access type, which I don't
+> believe I have ever used).
+
+Luckily you don't work for me, because anyone that "regularly used anonymous
+access parameters" here would be subject to termination for not following the
+coding guidelines! :-)
+
+The only time I've ever used anonymous access parameters was in the Claw
+Builder, and that was as a stand-in for the non-existent "in out" parameters for
+functions. Luckily we've fixed *that* lack.
+
+> It is true that Ada never allowed an anonymous array type as a
+> parameter type, while allowing it for stand-alone objects.
+> I would think there are still arguments on both sides of this decision
+> (I think we know where you stand), and I guess I am convinced that we
+> should be consistent -- if we think it is important to allow
+> "Vector(Positive, My_Rec)"
+> as a formal parameter subtype, then we should similarly allow
+> "array(Positive range <>) of My_Rec".  I think it would be worth
+> debating this issue in an ARG meeting, because e-mail does not provide
+> a good decision process.
+
+I certainly agree that we should be consistent. But that's tough because a
+parameter profile can't allow anything that requires evaluation/runtime
+elaboration. So, for instance, "array(Positive range <>) of My_Rec" is OK, and
+"array(Positive range <>) of My_Rec(N)" is not (assuming N is not static). The
+complications make it arguable whether it is worth it. (You have similar
+problems with anonymous instances, of course.)
+
+> The next question would be should we allow implicit instantiations as
+> part of a type declaration?  E.g.:
+>
+>     "type Vec_Rec is new Vectors.Vector(Positive, My_Rec);"
+>
+> Here the array type provides a clearer model, that yes, if we allow it
+> for a stand-alone object declaration, we should allow it in a type
+> declaration.
+>
+> This at least allows us to eliminate one level of explicit
+> instantiation.
+
+My initial thought was that this is fine, (with the obvious cavat that this is a
+tagged type, so there has to be a null extension on the type) but then I
+remembered that you can't usefully derive a type in a containers package. That's
+because a lot of the important operations aren't primitive for a container type
+(they're on the cursor type only) and thus they don't come along [formally:
+aren't inherited]. (A side issue is that the cursor type ends up being the same,
+which is more of a problem for non-null extensions where you may not want the
+cursor to point into both old and new containers. I once spent quite a bit of
+time trying to solve this problem with "co-derivation", but it didn't seem to
+work out well. That's definitely a problem that needs a solution, not just for
+the containers but in general).
+
+> So perhaps we can agree on some of this, and we can leave the debate
+> about the implicit instantiation as part of a formal parameter
+> specification for an ARG meeting (perhaps over a few beers...).  Along
+> with perhaps the discussion of whether implicit instantations should
+> be permitted for "state-ful"
+> generic packages, and maybe explicit type conversion rules. ;-)
+
+That was what I was trying to do with the proposal I made in the AI that started
+this thread. :-)
+
+Perhaps you could take a look at it (since obviously I don't object to it) and
+make suggestions for extensions as opposed to starting with your similar
+proposal that is IMHO an unexceptable mess?
+
+> > ... (I could see some use to an easier way to describe generic
+> > formal parameters of "any" vector type, for instance -- one can do
+> > that with formal packages, but it is clunky).
+>
+> I agree, that is clearly of value, and much more pleasant than the
+> complexities of formal packages.
+
+I don't have any ideas for that, though, so someone else will need to come up
+with one.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 12, 2017  7:03 AM
+
+>> ...
+
+> ... The only time I've ever used anonymous access parameters was in
+> the Claw Builder, and that was as a stand-in for the non-existent "in
+> out" parameters for functions. Luckily we've fixed *that* lack.
+
+If you are generally passing around access types, and you want to get some
+dispatching, then access parameters are quite appropriate, in my experience.  I
+agree that using them for function out-parameters is not important any more, and
+was somewhat of a kludge before.
+
+>> It is true that Ada never allowed an anonymous array type as a
+>> parameter type, while allowing it for stand-alone objects.
+>> I would think there are still arguments on both sides of this
+>> decision (I think we know where you stand), and I guess I am
+>> convinced that we should be consistent -- if we think it is important
+>> to allow "Vector(Positive, My_Rec)"
+>> as a formal parameter subtype, then we should similarly allow
+>> "array(Positive range <>) of My_Rec".  I think it would be worth
+>> debating this issue in an ARG meeting, because e-mail does not
+>> provide a good decision process.
+>
+> I certainly agree that we should be consistent. But that's tough
+> because a parameter profile can't allow anything that requires
+> evaluation/runtime elaboration. So, for instance, "array(Positive
+> range <>) of My_Rec" is OK, and "array(Positive range <>) of
+> My_Rec(N)" is not (assuming N is not static). The complications make
+> it arguable whether it is worth it. (You have similar problems with
+> anonymous instances, of course.)
+
+The semantics could be defined even in this case -- the subtypes are elaborated
+at the point of the subprogram declaration, and then rely on conformance -- but
+it would also be reasonable to require that there be no references to variables,
+only constants, in the parameter subtype specifications.  I don't see it as
+particularly difficult to specify the rules, but I agree that whether the
+feature has sufficient benefit is still debatable.
+
+>> The next question would be should we allow implicit instantiations as
+>> part of a type declaration?  E.g.:
+>>
+>>     "type Vec_Rec is new Vectors.Vector(Positive, My_Rec);"
+>>
+>> Here the array type provides a clearer model, that yes, if we allow
+>> it for a stand-alone object declaration, we should allow it in a type
+>> declaration.
+>>
+>> This at least allows us to eliminate one level of explicit
+>> instantiation.
+>
+> My initial thought was that this is fine, (with the obvious caveat
+> that this is a tagged type, so there has to be a null extension on the
+> type) but then I remembered that you can't usefully derive a type in a
+> containers package.
+
+This seems more of a failing of the structure of the containers packages, and
+doesn't argue against the value of the feature more generally.  As you mention
+below, and we have discovered for other reasons in the context of SPARK, having
+cursor operations that don't take the associated container as a parameter create
+numerous problems when it comes to doing anything "formal" with the containers.
+
+>> So perhaps we can agree on some of this, and we can leave the debate
+>> about the implicit instantiation as part of a formal parameter
+>> specification for an ARG meeting (perhaps over a few beers...).
+>> Along with perhaps the discussion of whether implicit instantations
+>> should be permitted for "state-ful"
+>> generic packages, and maybe explicit type conversion rules. ;-)
+>
+> That was what I was trying to do with the proposal I made in the AI
+> that started this thread. :-) ...
+
+Fair enough, but I believe we have made progress in this back-and-forth in terms
+of understanding where are the challenges, and the differences in views.
+
+>>> ... (I could see some use to an easier way to describe generic
+>>> formal parameters of "any" vector type, for instance -- one can do
+>>> that with formal packages, but it is clunky).
+>>
+>> I agree, that is clearly of value, and much more pleasant than the
+>> complexities of formal packages.
+>
+> I don't have any ideas for that, though, so someone else will need to
+> come up with one.
+
+All I know is that it will probably use "<>" in various places... ;-)
+
+****************************************************************
+
+From: Jeff Cousins
+Sent: Thursday, January 12, 2017  8:08 AM
+
+I'm afraid Tucker doesn't seem to be convincing people that we need anything
+more than what is in Randy's proposal. Would a fuller example help?  Maybe
+something based on the nested containers examples in the indefinite containers
+sections of Programming in Ada 2012?
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, January 12, 2017  2:25 PM
+
+> Along with perhaps the discussion of whether implicit instantations
+> should be permitted for "state-ful" generic packages
+
+[Another message...]
+> If you have the following code in library 1, from vendor A:
+>
+> procedure Frobulize (Vec : Vectors.Vector (Natural, Integer));
+>
+> And the following code in library 2, from vendor B:
+>
+> function Create_Sequence return Vectors.Vector (Natural, Integer);
+>
+> You want to be able to use those two subprograms together seamlessly, without
+> using conversion functions.
+
+I get wary when we start talking about combining implicit instantiations of
+"state-ful" generic packages with more complicated models aimed at cutting down
+on the number of implicitly-declared instances by coalescing multiple such
+instances into one.
+
+In the case of a "state-ful" package, I would strongly disagree with RaphaŽl's
+statement (perhaps RaphaŽl shares my opinion and had only state-less instances
+in mind). If two instances which happen to have the same actual parameters are
+not really interchangeable, then I want it to be very clear which one I am
+talking about at any given point.
+
+Incidentally, my notion of "state-ful" is fairly conservative.
+
+Consider, for example
+
+     generic
+        type T is private;
+     package G1 is
+        X : constant Integer := Some_Package.Some_Global_Variable;
+        type Rec is
+          record
+             F1 : Integer := X;
+             F2 : T;
+          end record;
+     end G;
+
+If I see
+
+    Var_1 : G1 (Float).Rec;
+
+in one place then I certainly don't want the presence or absence of
+
+    Var_2 : G1 (Float).Rec;
+
+in another place to influence the initial value of Var_1.F1 by somehow affecting
+the point at which the relevant instance of G1 is elaborated.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 12, 2017  3:08 PM
+
+>> Along with perhaps the discussion of whether implicit instantations
+>> should be permitted for "state-ful" generic packages
+
+If it wasn't clear, I am not a fan of allowing implicit instantiation of
+state-ful generic packages.  And I would agree that state-less implies you don't
+want something that captures the value of a global variable upon instantiation
+-- you really want the instantiations to produce the same result given the same
+actual parameters.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 12, 2017  3:46 PM
+
+> > ... The only time I've ever used anonymous access parameters was in
+> > the Claw Builder, and that was as a stand-in for the
+> non-existent "in
+> > out" parameters for functions. Luckily we've fixed *that* lack.
+>
+> If you are generally passing around access types, and you want to get
+> some dispatching, then access parameters are quite appropriate, in my
+> experience.
+
+I've said this before, so I'll be brief (for me!): Using access parameters in
+this way save 4 characters (".all"), which hardly is enough for the complexity
+of the feature in the first place. And ADTs that "pass around access types" are
+unnecessarily limiting, as they force a memory management style on the user,
+preventing them from using containers, local objects, or even smart pointers for
+memory management. That might be OK for one-time use quick & dirty code, but not
+anything that might get reused (and a lot of code has reuse potential). I don't
+think the language should be designed to specifically help quick & dirty code.
+
+...
+> I agree that using them
+> for function out-parameters is not important any more, and was
+> somewhat of a kludge before.
+> >
+> >> It is true that Ada never allowed an anonymous array type as a
+> >> parameter type, while allowing it for stand-alone objects.
+> >> I would think there are still arguments on both sides of this
+> >> decision (I think we know where you stand), and I guess I am
+> >> convinced that we should be consistent -- if we think it is
+> >> important to allow "Vector(Positive, My_Rec)"
+> >> as a formal parameter subtype, then we should similarly allow
+> >> "array(Positive range <>) of My_Rec".  I think it would be worth
+> >> debating this issue in an ARG meeting, because e-mail does not
+> >> provide a good decision process.
+> >
+> > I certainly agree that we should be consistent. But that's tough
+> > because a parameter profile can't allow anything that requires
+> > evaluation/runtime elaboration. So, for instance, "array(Positive
+> > range <>) of My_Rec" is OK, and "array(Positive range <>) of
+> > My_Rec(N)" is not (assuming N is not static). The complications make
+> > it arguable whether it is worth it. (You have similar problems with
+> > anonymous instances, of course.)
+>
+> The semantics could be defined even in this case -- the subtypes are
+> elaborated at the point of the subprogram declaration, and then rely
+> on conformance -- but it would also be reasonable to require that
+> there be no references to variables, only constants, in the parameter
+> subtype specifications.  I don't see it as particularly difficult to
+> specify the rules, but I agree that whether the feature has sufficient
+> benefit is still debatable.
+
+Yes, and whether the language design inconsistency (that dynamic constraints are
+allowed everywhere but in a profile) is more trouble than it is worth. It's easy
+to explain the restriction to identifiers without having to get into the
+semantic problems in detail - it seems natural in a "name everything" language
+design. A restriction to static constraints pretty much would require some sort
+of semantic explanation (and we'd still get pressure from the underinformed to
+eliminate the restriction).
+
+...
+> >> The next question would be should we allow implicit instantiations
+> >> as part of a type declaration?  E.g.:
+> >>
+> >>     "type Vec_Rec is new Vectors.Vector(Positive, My_Rec);"
+> >>
+> >> Here the array type provides a clearer model, that yes, if we allow
+> >> it for a stand-alone object declaration, we should allow it in a
+> >> type declaration.
+> >>
+> >> This at least allows us to eliminate one level of explicit
+> >> instantiation.
+> >
+> > My initial thought was that this is fine, (with the obvious caveat
+> > that this is a tagged type, so there has to be a null extension on
+> > the
+> > type) but then I remembered that you can't usefully derive
+> a type in a containers package.
+>
+> This seems more of a failing of the structure of the containers
+> packages, and doesn't argue against the value of the feature more
+> generally.  As you mention below, and we have discovered for other
+> reasons in the context of SPARK, having cursor operations that don't
+> take the associated container as a parameter create numerous problems
+> when it comes to doing anything "formal" with the containers.
+
+I take it from this that you agree with my suggestion to add the missing
+container reading operations so that derivation and formal analysis work
+appropriately? (I made that a separate thread, that no one seems to have
+commented on so far.) We can't get rid of the existing operations for obvious
+reasons, but we could add ones that work "right" and formal uses could just
+ignore the ones without a container parameter. (That seems like a more practical
+solution than defining a completely separate set of containers that have better
+behavior.) [Comment on my other message if possible, that helps keep the threads
+together.]
+
+> >> So perhaps we can agree on some of this, and we can leave the
+> >> debate about the implicit instantiation as part of a formal
+> >> parameter specification for an ARG meeting (perhaps over a few beers...).
+> >> Along with perhaps the discussion of whether implicit instantations
+> >> should be permitted for "state-ful"
+> >> generic packages, and maybe explicit type conversion rules. ;-)
+> >
+> > That was what I was trying to do with the proposal I made in the AI
+> > that started this thread. :-) ...
+>
+> Fair enough, but I believe we have made progress in this
+> back-and-forth in terms of understanding where are the challenges, and
+> the differences in views.
+
+Yes, we have.
+
+> >>> ... (I could see some use to an easier way to describe generic
+> >>> formal parameters of "any" vector type, for instance -- one can do
+> >>> that with formal packages, but it is clunky).
+> >>
+> >> I agree, that is clearly of value, and much more pleasant than the
+> >> complexities of formal packages.
+> >
+> > I don't have any ideas for that, though, so someone else will need
+> > to come up with one.
+>
+> All I know is that it will probably use "<>" in various places... ;-)
+
+Yup. Someone needs to construct an example of how it would be done today so that
+we can see where the verbosity and challenges lie. I'd do it myself, but it
+wouldn't do to use up my entire 2017 budget in the first two weeks of January...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 12, 2017  4:21 PM
+
+> >> Along with perhaps the discussion of whether implicit instantations
+> >> should be permitted for "state-ful" generic packages
+>
+> If it wasn't clear, I am not a fan of allowing implicit instantiation
+> of state-ful generic packages.
+
+That only matters, though, if you are doing some sort of instance combining. If
+it is one instance to one implicit usage (in parallel with anonymous arrays),
+then it does not matter.
+
+> And I would
+> agree that state-less implies you don't want something that captures
+> the value of a global variable upon instantiation -- you really want
+> the instantiations to produce the same result given the same actual
+> parameters.
+
+I worry that a state-less restriction would be about as useful as Pure packages:
+they sound like a good idea, but are very difficult to use in practice. There
+always seems to be some reason that something not allowed in a Pure package is
+needed (often for debugging, frequently for other things). That same would seem
+likely here; as I noted, all of the non-pure Ada.Containers packages have state
+in Janus/Ada. And debugging often involves local state.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 12, 2017  4:31 PM
+
+> ... I've said this before, so I'll be brief (for me!): Using access
+> parameters in this way save 4 characters (".all"), which hardly is
+> enough for the complexity of the feature in the first place. And ADTs
+> that "pass around access types" are unnecessarily limiting, as they
+> force a memory management style on the user, preventing them from
+> using containers, local objects, or even smart pointers for memory
+> management. That might be OK for one-time use quick & dirty code, but
+> not anything that might get reused (and a lot of code has reuse
+> potential). I don't think the language should be designed to specifically help
+> quick & dirty code.
+
+You are presuming quite a lot here about how people structure O-O systems, and
+clearly we are not about to get rid of access parameters.  So I would suggest we
+don't spend too much energy arguing about whose approach is appropriate for any
+given O-O system, since it seems pretty much beside the point for this
+discussion.
+
+> ... I take it from this that you agree with my suggestion to add the
+> missing container reading operations so that derivation and formal
+> analysis work appropriately? (I made that a separate thread, that no
+> one seems to have commented on so far.)
+
+Yes, I agree with that proposal.
+
+> ... We can't get rid of the existing operations for obvious reasons,
+> but we could add ones that work "right" and formal uses could just
+> ignore the ones without a container parameter. (That seems like a more
+> practical solution than defining a completely separate set of
+> containers that have better behavior.) [Comment on my other message if
+> possible, that helps keep the threads together.]
+
+When I have a bit more time, I will do so.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 12, 2017  4:39 PM
+
+>> If it wasn't clear, I am not a fan of allowing implicit instantiation
+>> of state-ful generic packages.
+>
+> That only matters, though, if you are doing some sort of instance combining.
+> If it is one instance to one implicit usage (in parallel with
+> anonymous arrays), then it does not matter.
+
+I guess I don't agree.  If one writes:
+
+    X, Y : Vectors.Vector(Natural, My_Rec);
+
+it is weird to have to worry that the order of X & Y might matter.
+
+>> And I would
+>> agree that state-less implies you don't want something that captures
+>> the value of a global variable upon instantiation -- you really want
+>> the instantiations to produce the same result given the same actual
+>> parameters.
+>
+> I worry that a state-less restriction would be about as useful as Pure
+> packages: they sound like a good idea, but are very difficult to use
+> in practice. There always seems to be some reason that something not
+> allowed in a Pure package is needed (often for debugging, frequently for
+> other things).
+> That same would seem likely here; as I noted, all of the non-pure
+> Ada.Containers packages have state in Janus/Ada. And debugging often
+> involves local state.
+
+A reasonable consideration, so we would have to see whether we can define
+"state-less" in a way that seems to work for almost all interesting container
+generics.  I'd be curious what "state" your Ada.Containers package have, and how
+that can work if you use the same instance to define objects manipulated in
+different tasks.  For what it is worth, I would presume that declaring an access
+type would be allowed in a "state-less" generic, despite the weirdness with Pure
+and access types (probably a major part of the problem with "Pure").
+
+As far as debugging, the old export/import trick seems to be a relatively common
+way to allow debugging I/O from a Pure package, but of course I would never do
+such a thing myself.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 12, 2017  4:48 PM
+
+...
+> > ... I've said this before, so I'll be brief (for me!): Using access
+> > parameters in this way save 4 characters (".all"), which hardly is
+> > enough for the complexity of the feature in the first place. And
+> > ADTs that "pass around access types" are unnecessarily limiting, as
+> > they force a memory management style on the user, preventing them
+> > from using containers, local objects, or even smart pointers for
+> > memory management. That might be OK for one-time use quick & dirty
+> > code, but not anything that might get reused (and a lot of code has
+> > reuse potential). I don't think the language should be designed
+> to specifically help quick & dirty code.
+>
+> You are presuming quite a lot here about how people structure O-O
+> systems,
+
+They structure them badly!! :-) A lot of designs are similar to C++ or Java
+designs, and Ada has additional capabilities that allow it to be done better.
+I'm not much interested in copying the mistakes of other languages...
+
+> ... and clearly we are not about to get rid of access parameters.  So
+> I would suggest we don't spend too much energy arguing about whose
+> approach is appropriate for any given O-O system, since it seems
+> pretty much beside the point for this discussion.
+
+...but I definitely agree with you here. (I minimized my justification of the
+above for exactly that reason.) It's only relevant to the point that I don't
+want to put any *additional* effort into features that I see as bad for Ada
+usage. (I'd be surprised if anyone here feels differently, but of course the
+features in question will differ.)
+
+...
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Thursday, January 12, 2017  11:25 PM
+
+>>> Along with perhaps the discussion of whether implicit instantations
+>>> should be permitted for "state-ful" generic packages
+>
+> If it wasn't clear, I am not a fan of allowing implicit instantiation
+> of state-ful generic packages.  And I would agree that state-less
+> implies you don't want something that captures the value of a global
+> variable upon instantiation -- you really want the instantiations to
+> produce the same result given the same actual parameters.
+
+But wouldn't it mean that sharing (or not) would depend on the generic body?
+We certainly don't want THAT!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, January 13, 2017  12:12 AM
+
+Tucker had suggested an aspect to mark such packages, so it wouldn't depend on
+the body.
+
+But we already have such an aspect (Pure), so what another similar aspect would
+buy us isn't clear to me. (Only the bounded containers are Pure, and that's for
+good reasons that would also apply to Tuck's "stateless" aspect, so his
+anonymous instances couldn't be used for most containers.)
+
+****************************************************************
+
+From: RaphaŽl Amiard
+Sent: Friday, January 13, 2017  3:22 AM
+
+> In the case of a "state-ful" package, I would strongly disagree with
+> RaphaŽl's statement (perhaps RaphaŽl shares my opinion and had only
+> state-less instances in mind).
+
+Yes, and yes.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, January 15, 2017  5:49 PM
+
+> They structure them badly!! :-)
+
+Off topic!! ;-)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, January 15, 2017  5:49 PM
+
+Finally got around to reading this monster thread.
+
+> I've said this before, so I'll be brief (for me!): Using access
+> parameters in this way save 4 characters (".all"), which hardly is
+> enough for the complexity of the feature in the first place. And ADTs
+> that "pass around access types" are unnecessarily limiting, as they
+> force a memory management style on the user, preventing them from
+> using containers, local objects, or even smart pointers for memory
+> management. That might be OK for one-time use quick & dirty code, but
+> not anything that might get reused (and a lot of code has reuse
+> potential). I don't think the language should be designed to specifically
+> help quick & dirty code.
+
+Unless everyone on ARG agrees with that point of view, then we shouldn't be
+designing the Ada programming language based on that point of view.
+You shouldn't be trying convince Tucker that he shouldn't be "passing around
+access values", and Tucker shouldn't be trying to convince you of the
+opposite. You should accept each other's different styles as valid, and design
+the language accordingly.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, January 15, 2017  5:50 PM
+
+> I guess I don't agree.  If one writes:
+>
+>     X, Y : Vectors.Vector(Natural, My_Rec);
+>
+> it is weird to have to worry that the order of X & Y might matter.
+
+Yes.  Arrays are broken for the same reason:
+
+    X, Y: array (1..Read(From => Keyboard)) of ...;
+
+> A reasonable consideration, so we would have to see whether we can
+> define "state-less" in a way that seems to work for almost all
+> interesting container generics.  I'd be curious what "state" your
+> Ada.Containers package have, and how that can work if you use the same
+> instance to define objects manipulated in different tasks.  For what
+> it is worth, I would presume that declaring an access type would be allowed in a "state-less" generic, despite the weirdness with Pure and access types (probably a major part of the problem with "Pure").
+
+Yes, I think it was a mistake to consider heap allocation to be a "side effect".
+After all, pure functional languages are lot purer than Ada, and they do heap
+allocation at the drop of a hat.
+
+Heap allocation is a side effect, yeah, but it shouldn't matter at the semantic
+level we care about, any more than the fact that running code has the side
+effect of increasing the temperature of the CPU chip.  (We would need to allow
+access types that don't have "=", though.)
+
+> As far as debugging, the old export/import trick seems to be a
+> relatively common way to allow debugging I/O from a Pure package, but of course I would never do such a thing myself.
+
+In my own language designing, I've invented ways of saying, "Never mind that
+this is Pure, I want to have a hidden side effect anyway, but I promise it's not
+a side effect that matters."  (Defining "matters" is tricky. And if it DOES
+matter, you get erroneousness.)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, January 15, 2017  5:52 PM
+
+> All I know is that it will probably use "<>" in various places... ;-)
+
+I once had a consulting gig where part of my job was to tutor a FORTRAN
+programming in Ada.  He asked, "What does '<>' mean in Ada?" That question
+wasn't easy to answer way back then, and it hasn't gotten easier.  ;-)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, January 15, 2017  5:56 PM
+
+> I certainly agree that we should be consistent. But that's tough
+> because a parameter profile can't allow anything that requires
+> evaluation/runtime elaboration.
+
+Why?  I have never understood why Ada doesn't allow:
+
+    procedure P (X: Integer range 1 .. N);
+
+I can think of three possible rules:
+
+    - N must be static.
+
+    - N need not be static, and:
+
+        - N is evaluated as part of the declaration of P.
+
+        - N is evaluated at each call site.
+
+As far as I can see, none of these introduce any semantic anomalies.
+The last one would allow some interesting things, if we also changed the
+visibility rules:
+
+    procedure P(S: String; X: Integer range S'Range := S'First);
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Monday, January 16, 2017  12:22 AM
+
+>> All I know is that it will probably use "<>" in various places... ;-)
+>
+> I once had a consulting gig where part of my job was to tutor a
+> FORTRAN programming in Ada.  He asked, "What does '<>' mean in Ada?"
+> That question wasn't easy to answer way back then, and it hasn't
+> gotten easier.  ;-)
+
+??
+In my courses, I explain: "it's a placeholder, meaning: something here will have
+to be filled later, like a box in a form showing wher to put your name".
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, January 16, 2017  8:06 PM
+
+> > I certainly agree that we should be consistent. But that's tough
+> > because a parameter profile can't allow anything that requires
+> > evaluation/runtime elaboration.
+>
+> Why?  I have never understood why Ada doesn't allow:
+>
+>     procedure P (X: Integer range 1 .. N);
+>
+> I can think of three possible rules:
+>
+>     - N must be static.
+>
+>     - N need not be static, and:
+>
+>         - N is evaluated as part of the declaration of P.
+>
+>         - N is evaluated at each call site.
+>
+> As far as I can see, none of these introduce any semantic anomalies.
+
+They're all inconsistent with the rest of the language. For the first rule, we
+don't restrict the use of dynamic constraints anywhere else. The second rule
+implies that bodies and declarations are treated differently for the evaluation
+of subtype_indications (or there has to be some form of dynamic conformance,
+which would be madness). That would be a mild maintanance hazard at best. The
+third rule is very inconsistent with the rest of the language; subtypes are
+always elaborated in place.
+
+Any of these might have made sense in a new language, but none of them seem very
+consistent with Ada.
+
+I recall we talked about this (informally?? - I didn't try to look this up) in
+the context of Ada 2005 and decided that a change wasn't likely to be in the
+best interest of Ada. That seems unlikely to have changed (although enough time
+and membership change has happened that we could discuss it again if there is
+enough interest).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, January 16, 2017  8:26 PM
+
+....
+> > For what it is worth, I would presume that declaring an access type
+> > would be allowed in a "state-less" generic, despite the weirdness
+> > with Pure and access types (probably a major part of the problem
+> > with "Pure").
+>
+> Yes, I think it was a mistake to consider heap allocation to be a
+> "side effect".  After all, pure functional languages are lot purer
+> than Ada, and they do heap allocation at the drop of a hat.
+>
+> Heap allocation is a side effect, yeah, but it shouldn't matter at the
+> semantic level we care about, any more than the fact that running code
+> has the side effect of increasing the temperature of the CPU chip.
+> (We would need to allow access types that don't have "=",
+> though.)
+
+Heap allocation per-se isn't the problem, the problem is that the allocated
+memory is (or maybe "can be") global and used by other tasks. For instance, Claw
+has many allocated objects that are used only locally, but since there is always
+another task (the human operator of the Claw program) that can change the state,
+one can never trust that (and as a consequence, pre-testing Claw objects is
+pointless). That has to be taken account in terms of things like Pure.
+
+"No allocation" is too strong a club, but just allowing any allocation
+necessarily allows cases of global state as well. Not sure how to reconcile
+that.
+
+> > As far as debugging, the old export/import trick seems to be a
+> > relatively common way to allow debugging I/O from a Pure
+> package, but of course I would never do such a thing myself.
+>
+> In my own language designing, I've invented ways of saying, "Never
+> mind that this is Pure, I want to have a hidden side effect anyway,
+> but I promise it's not a side effect that matters."  (Defining
+> "matters" is tricky.
+> And if it DOES matter, you get erroneousness.)
+
+The problem with that is that it depends on the use of Pure as to whether any
+side-effects can be allowed. For optimization purposes, such a declaration (of
+"trust me") is clearly fine. OTOH, if one is trying to determine what is safe to
+use in a parallel loop, any side-effect is going to be trouble (because of the
+unsynchronized use of the side-effect).
+
+The existing Ada Pure is at the wrong level for pretty much any use; hopefully
+the proposed Global aspect will do a better job (by being finer-grained - both
+as to what it applies and to what is used).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, January 16, 2017  8:39 PM
+
+...
+> Unless everyone on ARG agrees with that point of view, then we
+> shouldn't be designing the Ada programming language based on that
+> point of view.
+> You shouldn't be trying convince Tucker that he shouldn't be "passing
+> around access values", and Tucker shouldn't be trying to convince you
+> of the opposite.  You should accept each other's different styles as
+> valid, and design the language accordingly.
+
+Everybody has "hot button" issues, and this is one of mine. One can respect the
+existence of other opinions while still being completely convinced that they're
+wrong. I want to spend as little time as possible on improving the language in
+ways that cannot possibly help the use of Ada, and certainly not to help the
+spread of dubious programming techniques.
+
+I would not expect any of our group to feel differently. Of course, compromise
+is possible (my entire intent with the proposal that started this thread was to
+try to find some sort of compromise; I don't see any real problem here but it
+seems clear that others do and I wanted to be part of the solution rather than
+just saying "no" repeatedly. There were 4 features of Tucker's original proposal
+that I consider unacceptable for Ada, so we were a LOOONNNGGG ways from
+compromise there -- I could have said "no chance in hell" and left it at that.
+In hindsight I probably should have done that...).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, January 16, 2017  9:00 PM
+
+...
+> >> If it wasn't clear, I am not a fan of allowing implicit
+> >> instantiation of state-ful generic packages.
+> >
+> > That only matters, though, if you are doing some sort of instance combining.
+> > If it is one instance to one implicit usage (in parallel with
+> > anonymous arrays), then it does not matter.
+>
+> I guess I don't agree.  If one writes:
+>
+>     X, Y : Vectors.Vector(Natural, My_Rec);
+>
+> it is weird to have to worry that the order of X & Y might matter.
+
+Why would it matter? If there are two separate instances, each with their own
+state, then the objects are fully independent. The order shouldn't matter. I
+suppose it could matter if you had some sort of mad generic which depends on a
+global variable outside of the instance and for which that dependence matters in
+some way that is visible in the dynamic semantics. But such a generic would be
+problematic in any use; you'd have care about the order of instantiations in any
+usage and that would be highly unusual (and difficult to use). I can't get very
+concerned about such cases (if it hurts, don't do that). Bob noted that the
+order matters for an anonymous array like:
+
+     X, Y : array (1 .. Some_Function) of Integer;
+
+where Some_Function is a function that returns different values on each call.
+But again such a declaration is so unusual it hardly pays to worry about it in
+terms of language rules. (One could imagine requiring any anonymous subtypes to
+be static, but Ada didn't take that path.)
+
+> >> And I would
+> >> agree that state-less implies you don't want something that
+> >> captures the value of a global variable upon instantiation -- you
+> >> really want the instantiations to produce the same result given the
+> >> same actual parameters.
+> >
+> > I worry that a state-less restriction would be about as useful as
+> > Pure
+> > packages: they sound like a good idea, but are very difficult to use
+> > in practice. There always seems to be some reason that something not
+> > allowed in a Pure package is needed (often for debugging, frequently
+> > for other things). That same would seem likely here; as I noted, all
+> > of the non-pure Ada.Containers packages have state in Janus/Ada. And
+> > debugging often involves local state.
+>
+> A reasonable consideration, so we would have to see whether we can
+> define "state-less" in a way that seems to work for almost all
+> interesting container generics.  I'd be curious what "state" your
+> Ada.Containers package have, and how that can work if you use the same
+> instance to define objects manipulated in different tasks.
+
+The state in the containers (different in each container, of course):
+(1) Storage pool-related stuff;
+(2) A serial-number generator for dangling cursor detection;
+(3) For the containers with individual nodes, pointers at a small number of
+    recently freed nodes;
+(4) Some performance measurement data (only when debugging).
+
+For Janus/Ada, which uses "run until task dispatching point" semantics, it's not
+a worry about surprise interruptions, so the tasking protection doesn't need
+much. (2) and (3) use atomic components to avoid tasking trouble; (1) uses the
+standard storage pool (which hopefully avoids tasking trouble); and (4)
+generally is only used in limited circumstances so I've never worried about what
+happens when tasking is involved.
+
+...
+> For what it is worth, I
+> would presume that declaring an access type would be allowed in a
+> "state-less" generic, despite the weirdness with Pure and access types
+> (probably a major part of the problem with "Pure").
+
+I mentioned in my reply to Bob that there certainly is some way to make that
+work, but one has to be careful about multiple tasks banging on the same heap
+allocated objects. Claw does that a lot and one has to be careful to not assume
+any Claw operations are Pure even though the implementation appears that way.
+Not sure what the solution is for that (it would be good to find one, for Global
+at least).
+
+> As far as debugging, the old export/import trick seems to be a
+> relatively common way to allow debugging I/O from a Pure package, but
+> of course I would never do such a thing myself.
+
+Me either, and I would like to have a way to debug things without having to
+resort to that (or to passing a Logger routine as a parameter to every routine,
+which is what I usually do).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, January 21, 2017  3:45 PM
+
+>> I guess I don't agree.  If one writes:
+>>
+>>     X, Y : Vectors.Vector(Natural, My_Rec);
+>>
+>> it is weird to have to worry that the order of X & Y might matter.
+>
+> Why would it matter? If there are two separate instances, each with
+> their own state, then the objects are fully independent.
+
+This was in the context of Steve's comment that related to his definition of
+"stateless" where he wanted to disallow references to global variables in the
+initialization of the package-level constants.  Even worse would be a case where
+a global variable is update during the elaboration of an instantiation.  Here is
+a quote from that e-mail:
+
+> ... Consider, for example
+>
+>     generic
+>        type T is private;
+>     package G1 is
+>        X : constant Integer := Some_Package.Some_Global_Variable;
+>        type Rec is
+>          record
+>             F1 : Integer := X;
+>             F2 : T;
+>          end record;
+>     end G;  ...
+
+
+> ... The order shouldn't
+> matter. I suppose it could matter if you had some sort of mad generic
+> which depends on a global variable outside of the instance and for
+> which that dependence matters in some way that is visible in the dynamic semantics. ...
+
+That is exactly what Steve was worrying about.  Steve is of course the master of
+"mad" generics (and other "mad" examples), which is helpful when you are trying
+to evaluate whether a given proposed rule actually provides some measure of
+safety.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Saturday, January 21, 2017  8:50 PM
+
+But why is such a "mad" generic a worry? There's no semantic problem with it,
+and it's not the sort of thing that a programmer is likely to do. After all, Ada
+always has had cases like that:
+
+    X, Y : Disc_Rec (Func);
+
+If Func returns a different value for each call, then X and Y have different
+constraints. (3.3.1(7)). If that's a problem, don't do it!
+
+Moreover, this kind of state could be useful in some cases. If one wanted each
+instance to have a unique serial number, for instance, one would use a global
+object and modify it during the elaboration of the instance. But the order
+wouldn't matter, just that the serial numbers are unique.
+
+So I don't see why this sort of thing is a concern. If it happens, one presumes
+that the programmer knows what they're doing. After all, there will never be a
+programming language in which it is the least bit hard to write ill-advised
+programs! (I remember someone saying that many years ago, and I doubt that has
+changed since.)
+
+I really don't want to define some complex mechanism that's rather like another
+mechanism (that didn't work out very well) just to avoid such an unlikely issue.
+It seems like massive overkill.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, January 21, 2017  10:01 AM
+
+> Not having to invent names is not a very good justification...
+
+Every name adds a cognitive burden to the reader of the program. It's easy to
+invent names, but having to read names and match them up with their declaration
+is a burden.
+
+That's why aspects are better than pragmas, for example. With the pragma you
+have to match the name in the pragma with the declaration it refers to.  Aspects
+are syntactically part of the declaration, so don't have that problem.
+
+>...But there
+> is (IMHO) at least one major value to anonymous types: you know it is
+>a  singleton, that it's the only object of its kind, and this can be a
+>useful information (especially for single tasks) that you want enforced
+>by the compiler...
+
+Agreed.
+
+> ... and that would be immediately broken with structural equivalence!
+
+Not if structural equivalence is triggered by some mechanism other than
+anonymity.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Saturday, January 21, 2017  8:41 PM
+
++1
+
+If structural equivalence is really useful, it shouldn't be mixed up with
+anonymity: I don't want any more incentives to use anonymity rather than named
+declarations. Ideally, the choice to omit named declarations is driven solely by
+the programmer's determination that an additional name doesn't help readability.
+Not by a desire to get dynamic accessibility or closures (both features that are
+bizarrely tied to anonymity today) or structural equivalence.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent