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

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

--- ai12s/ai12-0257-1.txt	2018/05/10 06:07:32	1.2
+++ ai12s/ai12-0257-1.txt	2020/01/31 05:51:39	1.3
@@ -1,7 +1,8 @@
-!standard 4.1.3(9.1/2)                                  18-02-22  AI12-0257-1/01
+!standard 4.1.3(9.1/2)                                  20-01-30  AI12-0257-1/02
 !standard 4.1.3(9.2/2)
 !class Amendment 18-02-22
-!status Hold by Letter Ballot (8-0-3) - 18-05-07 
+!status work item 20-01-30
+!status Hold by Letter Ballot (8-0-3) - 18-05-07
 !status work item 18-02-22
 !status received 18-03-20
 !priority Very_Low
@@ -9,7 +10,7 @@
 !subject Generalize prefix views
 !summary
 
-Prefixed views are allowed on untagged private types.
+Prefixed views are allowed on all (?) types.
 
 !problem
 
@@ -20,44 +21,171 @@
 
 !proposal
 
-We have to decide how to handle prefixed views on full types of untagged
-private types.
+There are four possible extensions to prefixed views:
 
-It would be unusual if the prefixed view wasn't allowed at all (unless the
-full type was tagged or access-to-tagged). That would mean that moving an
-a subprogram previously defined in client code into the package of an
-abstraction could fail to compile if it used any prefixed views.
-
-However, since allowing prefixed views on access types would be incompatible
-(and complex), we can't allow that to be required.
-
-Probably the best rule would be something like a prefixed view is allowed
-on an untagged private type, or an untagged non-access type that is the 
-full type of a private type.
-
-We'd still have the weird case for access types; we could allow prefixed views
-on those so long as they don't designate a tagged type and so long as the
-dereferences of the access values aren't considered -- but that's nearly as
-weird as not allowing prefixed views there at all.
+(1) Allow them on all types without restrictions.
 
+(2) Allow them only on record types (tagged and untagged). (Presumably
+with a way to declare that a private type will be completed with a
+record.)
+
+(3) Allow them on tagged types and untagged types with partial views.
+
+(4) Allow them on record types and untagged types with partial views.
+
+The pros and cons of these proposals are explored in the !discussion.
+
 !wording
 
 ** TBD.
 
 !discussion
+
+Supporting prefixed views on just untagged private types (as well as the
+current tagged types) initially seems appealing (as it side-steps the access
+problem).
+
+It would be unusual if the prefixed view wasn't allowed at all on the full
+type of an untagged private type (unless the full type was tagged or
+access-to-tagged). That would mean that moving a subprogram previously
+defined in client code into the package of an abstraction could fail to
+compile if it used any prefixed views. (This could happen if the package
+was changed to be a child of the package that defines the type, for one
+example.)
+
+Therefore, we do not consider untagged private types alone as a viable option.
+
+----
 
-Unfortunately allowing prefixed views on all types would be incompatible.
+Unfortunately allowing prefixed views on any access types (all but option (2))
+would be incompatible.
 
     Ptr.Id
 
 could mean Id(Ptr) or Id(Ptr.all). Currently, Id(Ptr) is not considered, so
 allowing prefixed views on all types could make some currently legal calls
-ambiguous.
+ambiguous. To work around such an ambiguity would require falling back to
+"regular" call notation, meaning that a "use" clause or lengthy selected
+notation would be required. But the entire reason for using prefixed notation
+is to avoid those things, so this is a nasty incompatibility.
+
+A second incompatibility is possible for any potential extension of prefixed
+notation. If the prefix is overloaded with a mix of tagged and untagged types,
+a prefixed call could become ambiguous. In this case, the problem can be
+worked around by qualifying the prefix, so the fix requires much less change.
+
+----
+
+Supporting prefixed views on all types is a precursor to obfuscated Ada
+contests, catching up with the C-family languages. For instance, as brought
+up at an ARG meeting:
+
+   if A."-"."/="(3)."not" then ...
+
+This means:
+
+   if not (-A /= 3) then...
+
+The value of prefix notation for scalar types (in particular) is unclear.
+OTOH, having a cleaner set of rules is important.
+
+----
+
+The current wording of 4.1.3 does not require subprograms to be primitive in
+order to use prefixed notation, rather only that they be declared in the same
+declarative region as the type. This is important for types that are declared
+in subprograms and blocks (for which no non-inherited subprograms are
+primitive). This seems to be an important property to preserve, especially as
+it is much more likely for untagged types to be declared outside of packages.
+
+----
+
+Regardless of what option is selected, care is needed that prefix calls and
+normal calls don't end up with different rules. In particular, the "implicit
+conversions" (they're not called that in Ada, they're just different types
+that can resolve) defined in 8.6 are not invoked by the 4.1.3 rules. That
+means that some calls that are legal by "normal" notation might not be legal
+for prefix notation.
+
+For instance, if we just struck "tagged" from 4.1.3(9.1-9.2/3), then consider:
+
+   package P1 is
+      type T1 is ...
+      procedure Process (P : access T1);
+      type AT1 is access T1'Class;
+      procedure Process2 (P : AT1);
+   end P1;
+
+   with P1;
+   package P2 is
+      type T2 is new P1.T1 with ...;
+      procedure Process (P : access T2);
+      type AT2 is access T2'Class;
+   end P2;
+
+   with P1;
+   package P3 is
+      type T3 is new P1.T1 with ..
+      procedure Process (P : access T3);
+      type GAT3 is access all T3'Class;
+      procedure Process3 (P : GAT3);
+   end P3;
+
+   declare
+      Obj1 : P1.At1 := ...;
+      Obj2 : P2.At2 := ...;
+      Obj3 : access P3.T3 := ...;
+   begin
+      Obj1.Process2; -- OK if rules changed, not allowed in Ada 2012.
+      Obj2.Process;  -- OK. (Actually Obj2.all'Access.Process).
+      Obj2.Process2; -- Nope. (Different access types.)
+                     -- Note: 'Access only tried for anonymous access params.
+      P1.Process (Obj1); -- OK.
+      P2.Process (Obj2); -- OK.
+      P1.Process2 (Obj2); -- Nope.
+      Obj3.Process;  -- OK. (Actually Obj3.all'Access.Process).
+      Obj3.Process3; -- Nope.
+      P3.Process (Obj3); -- OK.
+      P3.Process3 (Obj3); -- OK by 8.6(26.1/3)
+   end;
+
+In order to avoid these sorts of problems, the wording of 4.1.3(9.2/3) would
+have to allow the various implicit conversions. Note that the oddity here is
+not changed by the rule changes; it already resolves differently in the two
+cases. There are many additional such cases that can happen if access types
+are allowed.
+
+If we make any change to the wording, we should definitely try to reduce
+these cases.
+
+----
+
+Option (2) requires some way to specify on a private type that the completion
+will be a record type so that prefix notation can be supported on the private
+type. This is necessary to avoid breaking privacy in the worst way. Note that
+"tagged" has this role in the current rules. (Without the notation, prefixed
+views would not be allowed on private types.)
+
+Two options have been suggested:
+
+An aspect:
+
+    type Priv is private with Prefix_Notation;
+
+[As always, this is shorthand for "Prefix_Notation => True".]
+
+Or a keyword in place of "tagged":
+
+    type Priv is record private;
+
+It's a little weird to affect resolution with an aspect (it usually only
+affects Legality Rules), but it would not be too far outside of the model.
+Using "record" also seems a bit weird.
 
 !ASIS
 
-[Not sure. It seems like some new capabilities might be needed,
-but I didn't check - Editor.]
+[Not sure. Most likely, the existing prefix notation support would be
+sufficient - Editor.]
 
 !ACATS test
 
@@ -71,13 +199,13 @@
 Sent: Saturday, January 20, 2018  10:32 AM
 
 > 0) Should Big_Integer and (especially) Big_Rational be visibly tagged?
-> 
-> If so, then we can use prefix notation on functions like Numerator and 
+>
+> If so, then we can use prefix notation on functions like Numerator and
 > Denominator. We could also consider deriving both versions (usual and
 > bounded) from an abstract ancestor.
 > ...
 
-Somewhat off topic, but should we consider generalizing prefix notation to all 
+Somewhat off topic, but should we consider generalizing prefix notation to all
 types, or at least all private types?  I can't remember any reason why prefix
 notation really needs tagged types to make sense.  Now that we have "use all
 type" clauses, we already know how to make all the relevant (primitive)
@@ -145,15 +273,15 @@
 Sent: Sunday, January 21, 2018  2:11 PM
 
 ...
-> Note that allowing all types now would in fact be incompatible, if Ptr 
-> and Ptr.all both had an Id primitive operation. Currently, the Ptr 
+> Note that allowing all types now would in fact be incompatible, if Ptr
+> and Ptr.all both had an Id primitive operation. Currently, the Ptr
 > operation isn't considered, so changing the rules could make some calls
 > ambigious.
 
 Good point.  So access types should probably be left out of the picture,
 except in service to other types via access parameters.
- 
-> Allowing private only was considered, but it would be weird if clients 
+
+> Allowing private only was considered, but it would be weird if clients
 > could use prefixed notation but the implementation of some type could not.
 
 This doesn't seem so odd to me now, in part because several of the features
@@ -192,12 +320,12 @@
 disappear on the full type. There is nothing like that in Ada currently. And
 we don't do anything currently to prevent infinite recursion in package bodies
 (spoken as someone who has a lot of experience with implementing "+", "=", and
-other overridden operations in terms of themselves); it's strange to suddenly 
+other overridden operations in terms of themselves); it's strange to suddenly
 care about that 40 years too late.
 
-> The term "partial view" might better be something like "abstraction 
-> view" or "external view" to emphasize how different it might be from 
-> the full/internal view.  It is not just a subset of the full view, but 
+> The term "partial view" might better be something like "abstraction
+> view" or "external view" to emphasize how different it might be from
+> the full/internal view.  It is not just a subset of the full view, but
 > rather a potentially quite different view.
 
 I suppose that could work, but it would take a lot of getting used to, as it
@@ -205,3 +333,2207 @@
 
 ****************************************************************
 
+From: Tucker Taft
+Sent: Wednesday, October 23, 2019  9:05 AM
+
+!topic Generalizing object.operation(...) notation
+!reference Ada 202x 2012 RM4.1.3(9-9.2/3), 6.3.1(20-21/4)
+!from Tucker Taft 2019-10-23
+!keywords prefix notation, object.operation notation
+!discussion
+
+This has come up several times, but it seems worth re-considering allowing the
+use of "object.Operation(...)" notation more generally.  We have taken some
+steps to unify tagged and untagged record types (e.g. as far as whether equality
+"reemerges" in generics and composite equality).  It would be nice to take
+another step to reduce the "specialness" of tagged types.
+
+As an indicator of the problem, there are situations some of us have seen where
+a type was made visibly tagged merely to get prefix notation.  This is a sign
+that the prefix notation has significant value, and probably shouldn't be tied
+to a type being visibly tagged.
+
+The simplest solution would be to allow prefix notation on any type when
+invoking one of its primitive operations.  Class-wide operations are not
+meaningful for untagged types, so that simplifies the problem somewhat.
+
+One challenge is access types, where allowing prefix notation would introduce
+potential ambiguity due to implicit dereference.  We could disallow access
+types, but then that would mean that a private type completed with an access
+type could not use prefix notation in any expression subject to full conformance
+checks, such as the default expression of some subprogram declared in the
+visible part of the package.  This could be solved by allowing conformance
+between a call using a prefixed-view and a regular call, though that would add
+complexity to the full conformance rules for expressions (6.3.1(20-21/4)).
+
+However, the ambiguity introduced by allowing access types to use prefixed
+notation does not seem excessive, and overload resolution already has a similar
+situation where a private tagged type happens to have a record component with
+the same name as a visible primitive operation (see 4.1.3(9.2/3)), and prefix
+notation that is acceptable in the visible part might be ambiguous or have a
+different interpretation (do we have a Beaujolais effect here??) in the private
+part.
+
+Slightly less radical would be to allow prefix notation on private types and
+record types.  Allowing it on private types introduces a similar problem in that
+the full type would need to be a record type for a default expression to use
+prefix notation, unless we relax the conformance rules.
+
+****************************************************************
+
+From: Arnaud Charlet
+Sent: Sunday, October 27, 2019  4:55 PM
+
+> One challenge is access types, where allowing prefix notation would
+> introduce potential ambiguity due to implicit dereference.  We could
+> disallow access types, but then that would mean that a private type
+> completed with an access type could not use prefix notation in any
+> expression subject to full conformance checks, such as the default
+> expression of some subprogram declared in the visible part of the package.
+> This could be solved by allowing conformance between a call using a
+> prefixed-view and a regular call, though that would add complexity to
+> the full conformance rules for expressions (6.3.1(20-21/4)).
+
+I would not bother on access types for non tagged types. This isn't where people
+have the need for the dotted notation outside of tagged types in my experience,
+so I'd be in favor of a simple model here.
+
+****************************************************************
+
+From: Luke A. Guest
+Sent: Sunday, October 27, 2019  4:58 PM
+
+> This has come up several times, but it seems worth re-considering allowing
+> the use of "object.Operation(...)" notation more generally.  We have taken
+> some steps to unify tagged and untagged record types (e.g. as far as whether
+> equality "reemerges" in generics and composite equality).  It would be nice
+> to take another step to reduce the "specialness" of tagged types.
+
+Yes, I would love to see Ada have something like D's UFCS
+(https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs).
+e.g.
+
+procedure Test_1 (Name : in Positive);
+
+Something : Positive := ...;
+
+Something.Test_1;
+
+But would this be allowed?
+
+procedure Test_2 (Name : in String);
+
+"Hello".Test_2;
+
+> One challenge is access types, where allowing prefix notation would
+> introduce potential ambiguity due to implicit dereference.  We could
+> disallow access types, but then that would mean that a private type
+> completed with an
+
+I don't think this is a good idea really as Ada already has in some places
+implicit dereferences, i.e. pointers to sub-programs.
+
+****************************************************************
+
+From: Alejandro R. Mosteo
+Sent: Wednesday, October 23, 2019  10:13 AM
+
+A couple of comments purely as a user:
+
+>As an indicator of the problem, there are situations some of us have seen
+>where a type was made visibly tagged merely to get prefix notation.  This
+>is a sign that the prefix notation has significant value, and probably
+>shouldn't be tied to a type being visibly tagged.
+
+I usually do this. The main reasons I do it are: 1) It allows function
+chaining [1]. 2) It eliminates the need to either "use" or prefix with
+package name.
+
+> The simplest solution would be to allow prefix notation on any type when
+> invoking one of its primitive operations.  Class-wide operations are not
+> meaningful for untagged types, so that simplifies the problem somewhat.
+
+I'm developing a couple of generic-intensive libraries [2] where non-primitive
+functions would greatly benefit from the aforementioned function chaining. I
+understand the big deterrent here is that a new "with" could generate
+ambiguity whereas now this can't happen?
+
+Just bringing up the point; I think there's a broader issue here that touches
+on implicit generics too.
+
+>One challenge is access types, where allowing prefix notation would introduce
+>potential ambiguity due to implicit dereference.  (...)
+
+All my experiences using reference types with implicit dereference involve
+sooner than later situations where I have to use the .Element.all to
+disambiguate or have the pointee type recognized. I'd say that cat is out of
+the bag.
+
+[1] https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax
+[2] https://github.com/mosteo/rxada
+
+****************************************************************
+
+From: Yannick Moy
+Sent: Monday, October 28, 2019  5:46 AM
+
+>The simplest solution would be to allow prefix notation on any type when
+>invoking one of its primitive operations.  Class-wide operations are not
+>meaningful for untagged types, so that simplifies the problem somewhat.
+
+I confirm this would be a very nice enhancement to Ada, that many users would
+welcome.
+
+>>One challenge is access types, where allowing prefix notation would
+>>introduce potential ambiguity due to implicit dereference.  We could
+>>disallow access types, but then that would mean that a private type
+>>completed with an access type could not use prefix notation in any
+>>expression subject to full conformance checks, such as the default
+>>expression of some subprogram declared in the visible part of the package.
+>>This could be solved by allowing conformance between a call using a
+>>prefixed-view and a regular call, though that would add complexity to the
+>>full conformance rules for expressions (6.3.1(20-21/4)).
+
+>I would not bother on access types for non tagged types. This isn't where
+>people have the need for the dotted notation outside of tagged types
+>in my experience, so I'd be in favor of a simple model here.
+
+I agree with Arno, a simpler model is enough and probably better for that
+feature.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, October 28, 2019  8:08 AM
+
+Unfortunately, there is no completely simple solution.  If we disallow using
+object.op() for access types but allow it for private types, we need to deal
+with private types that are implemented using an access type.  It is always
+awkward to allow something on a private type but not on its full view.  In any
+case, given the apparent support for this idea, the ARG can work to come up
+with a set of rules that are good on the usability side, even if there are
+some complexities behind the scene.
+
+One approach might be to allow object.op() only on access types that have a
+partial view (i.e. that implement a private type).  That way the full type
+allows the same capabilities as the partial view.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, October 28, 2019  12:17 PM
+
+> Unfortunately, there is no completely simple solution.
+
+I can think of one.  ;-)
+
+It's not sufficiently broken, so don't fix it.
+
+****************************************************************
+
+From: Egil Harald Hoevik
+Sent: Monday, October 28, 2019  9:05 AM
+
+> The simplest solution would be to allow prefix notation on any type
+> when invoking one of its primitive operations.  Class-wide operations
+> are not meaningful for untagged types, so that simplifies the problem
+> somewhat.
+
+I can imagine some confusion with functions returning the type,  enumarators
+especially, ie:
+
+type Colour is (Red, Green, Blue);
+Tint : Colour := Red.Green.Blue;
+
+or
+
+return True.False;
+
+****************************************************************
+
+From: Egil Harald Hoevik
+Sent: Monday, October 28, 2019  9:49 AM
+
+> But would this be allowed?
+>
+> procedure Test_2 (Name : in String);
+>
+> "Hello".Test_2;
+>
+
+Or this?
+
+Put_Line( "Hello"."&"( "World" ) );
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, October 28, 2019  10:13 PM
+
+...
+>Unfortunately, there is no completely simple solution.  If we disallow
+>using object.op() for access types but allow it for private types, we need
+>to deal with private types that are implemented using an access type.  It is
+>always awkward to allow something on a private type but not on its full view.
+>In any case, given the apparent support for this idea, the ARG can work to
+>come up with a set of rules that are good on the usability side, even if
+>there are some complexities behind the scene.
+
+I don't think that a version of rules that allow private types to *lose*
+capabilities when the full view is seen is going to fly. And the access type
+problems were pretty severe as I recall, allowing them ever is likely to be
+trouble.
+
+I rather liked your idea of only allowing Object.Op on (all) record types.
+This would be similar to how we handled composition of equality, and that was
+for similar reasons -- doing it generally lead to oddities (see the disgusting
+examples with enumeration literals that some recently sent). It's always
+possible to wrap something in a record if that is needed to get Object.Op, and
+my experience is that seems to happen a lot anyway.
+
+As far as private types go, I think it has to be syntactically part of the
+private type. That's currently the case with "tagged". We could add something
+else where "tagged" is (say "record"), or we could define an aspect for the
+purpose. Usability would suggest the less the better, so a keyword seems
+preferable.
+
+It would be nice for usability to allow private types to allow Object.Op by
+default, but that then requires the completion to be a record type. That's
+likely to be the case in about 95% of examples already (it's *hard* to create
+viable examples where a private type is not completed with a record
+-- I've needed to do that for various ACATS tests and it tends to not work
+well, especially access types), but forcing people to change 5% of their
+existing code isn't likely to go over well.
+
+So I'd suggest something like:
+     type Priv is record private;
+which of course requires the completion to be a record type (untagged or
+tagged), and then Object.Op can be allowed on it and all record types without
+much complication.
+
+This seems like the simplest solution (short of the one Bob suggested :-).
+It doesn't allow *every* possibility, but the vast majority of the practical
+ones.
+
+****************************************************************
+
+From: Yannick Moy
+Sent: Tuesday, October 29, 2019  3:48 AM
+
+I agree with Randy on his proposed solution:
+
+> So I'd suggest something like:
+>     type Priv is record private;
+> which of course requires the completion to be a record type (untagged
+> or tagged), and then Object.Op can be allowed on it and all record
+> types without much complication.
+>
+> This seems like the simplest solution (short of the one Bob suggested :-).
+> It doesn't allow *every* possibility, but the vast majority of the
+> practical ones.
+
+and that dot-notation would only be allowed for primitive operations of the
+type, not any subprogram, to avoid the problem with with-clauses introducing
+ambiguities.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 29, 2019  8:01 AM
+
+I am not a real fan of adding syntax for this ("record private").  What about
+the suggestion of allowing it on a primitive function of any type that has a
+partial view?
+
+The enumeration literal example is a red herring -- this would only work on
+primitive functions that have at least one parameter, which is of the type
+for which it is a primitive.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 29, 2019  8:03 AM
+
+> I can imagine some confusion with functions returning the type,  enumarators
+> especially, ie:
+>
+> type Colour is (Red, Green, Blue);
+> Tint : Colour := Red.Green.Blue;
+
+This would not be legal, because the parameter profile of an enumeration
+literal, such as "Green", is:
+
+   function Green return Colour;
+
+while to use "object.op()" notation, the operation has to have at least one
+parameter, and the first parameter has to be of the type for which it is
+primitive.
+
+> or
+>
+> return True.False;
+
+Again, not legal since False does not have any parameters.
+
+****************************************************************
+
+From: Egil Harald Hoevik
+Sent: Tuesday, October 29, 2019  8:18 AM
+
+...
+> while to use "object.op()" notation, the operation has to have at
+> least one parameter, and the first parameter has to be of the type for which
+> it is primitive.
+
+So then it's a more complex solution than just "when invoking one of its
+primitive operations".
+
+****************************************************************
+
+From: Yannick Moy
+Sent: Tuesday, October 29, 2019  8:17 AM
+
+> I am not a real fan of adding syntax for this ("record private").  What
+> about the suggestion of allowing it on a primitive function of any type
+> that has a partial view?
+
+Then how do you allow dot-notation on a private type that is not derived
+from another type?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 29, 2019  8:27 AM
+
+Not sure I understand the question.  The suggestion was that object.op() is
+available on private types, as well as on the full view of the type.  By
+saying a type "has a partial view" all that means is that it implements a
+private type.  And every private type is implemented by some "full" type.
+
+****************************************************************
+
+From: Yannick Moy
+Sent: Tuesday, October 29, 2019  8:38 AM
+
+> The suggestion was that object.op() is available on private types, as well
+> as on the full view of the type.  By saying a type "has a partial view" all
+> that means is that it implements a private type.  And every private type is
+>  implemented by some "full" type.
+
+Indeed that clarifies your point, thanks.
+How does that solve the issue that you initially raised about implicit
+dereference? My understanding was that Randy's proposal precisely avoided any
+further complications here.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 29, 2019  8:32 AM
+
+> So then it's a more complex solution than just "when invoking one of its
+> primitive operations".
+
+The current object.op() feature (see RM 4.1.3(9.1-9.2)) is only defined on
+primitive subprograms (and "class wide" subprograms) of tagged types, and the
+object that comes out front is used as the first parameter.  The proposal was
+to generalize that to the primitive subprograms of other types (I wrote
+"primitive function" in an earlier e-mail, but I really meant "primitive
+subprogram").  There was no intent to generalize it to primitives with no
+parameters, or with the "controlling" parameter being something other than the
+first parameter.  Sorry if I implied otherwise.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 29, 2019  8:34 AM
+
+I should have said "primitive subprogram" rather than "primitive function" in
+the following...
+...
+> I am not a real fan of adding syntax for this ("record private").  What
+> about the suggestion of allowing it on a primitive function of any type
+> that has a partial view?
+>
+> The enumeration literal example is a red herring -- this would only work
+> on primitive functions that have at least one parameter, which is of the
+> type for which it is a primitive.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 29, 2019  9:16 AM
+
+...
+> How does that solve the issue that you initially raised about implicit
+> dereference?
+
+The problem if we allow object.op() on all access types, is that you end up
+having lots of possibilities for ambiguities.  By limiting it to access types
+that "complete" a private type, you limit it to operations that were defined
+as part of defining a private type.   If you were to allow them on any named
+access type, you would have lots of operations that were "primitive" on the
+type by chance because they happen to have the named access type as their
+first parameter, but without any real intent to being "primitive" in the
+logical sense.  So it is a question of degree.  You will still have the
+possibility for ambiguity, but should be dramatically decreased, and should
+not involve the same level of potential surprise for the user.
+
+> My understanding was that Randy's proposal precisely avoided any further
+> complications here.
+
+Perhaps, but it introduces a very nasty need to go back and add "record" to
+hundreds of existing private types on the off chance someone will want to use
+object.op() notation, and perhaps introduce record wrappers, which would then
+imply changing lots of package-body code that will now need an extra level of
+selection.  This is exactly the kind of change that people hate having to do,
+when all they want is to be able to use "object.op()" notation with their
+private type.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, October 29, 2019  9:32 AM
+
+> ...and perhaps introduce record wrappers,
+
+Wrapping things in records can be pretty painful, readability wise.
+Whenever you want to do anything, you have to put Rec.Blah, and then you have
+to put (Blah => ...) when you're done to wrap it back up.
+
+****************************************************************
+
+From: Jeffrey R. Carter
+Sent: Tuesday, October 29, 2019  11:43 AM
+
+> So I'd suggest something like:
+>      type Priv is record private;
+
+type Priv is private record;
+
+reads better.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, October 29, 2019  6:52 PM
+
+> > ...and perhaps introduce record wrappers,
+>
+> Wrapping things in records can be pretty painful, readability wise.
+> Whenever you want to do anything, you have to put Rec.Blah, and then
+> you have to put (Blah => ...) when you're done to wrap it back up.
+
+Agreed, but we are talking about things that almost always end up as records
+anyway (that is, ADTs). Object.Op implies a form of ADT, and certainly should
+not be used on non-ADTs (like any visible elementary type). It probably ought
+not be supported by every ADT, either, even if completed by a record.
+
+Pretty much every time that I started out making a private type something
+other than a record, I had to ultimately change it to a record. Not making it
+a record in the first place is simply a self-inflicted pain. So there should
+be very little need to add wrapping after the fact.
+
+It's not worth the complication to figure out how to deal with the unusual
+case where a private type is completed by some elementary type.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, October 29, 2019  7:10 PM
+
+> >> The suggestion was that object.op() is available on
+> >> private types, as well as on the full view of the type.  By saying a
+> >> type "has a partial view" all that means is that it implements a
+> >> private type.  And every private type is implemented by some "full"
+> >> type.
+> >
+> > Indeed that clarifies your point, thanks.
+> > How does that solve the issue that you initially raised
+> > about implicit dereference?
+>
+> The problem if we allow object.op() on all access types, is that you
+> end up having lots of possibilities for ambiguities.
+>  By limiting it to access types that "complete" a private type, you
+> limit it to operations that were defined as part of
+> defining a private type.   If you were to allow them on any
+> named access type, you would have lots of operations that were
+> "primitive" on the type by chance because they happen to have the
+> named access type as their first parameter, but without any real
+> intent to being "primitive" in the logical sense.  So it is a question
+> of degree.  You will still have the possibility for ambiguity, but
+> should be dramatically decreased, and should not involve the same
+> level of potential surprise for the user.
+
+I don't buy this for a moment. I find this a bad idea, simply because it has all
+of the complications (from a language design perspective) of unlimited
+Object.Op(), but you are only allowed to use it in a rare case that almost never
+works in practice. If we're going to go through all of the horrible issues from
+a language-design perspective, then we might as well allow it everywhere.
+
+> > My understanding was that Randy's proposal precisely
+> > avoided any further complications here.
+>
+> Perhaps, but it introduces a very nasty need to go back and add
+> "record" to hundreds of existing private types on the off chance
+> someone will want to use object.op() notation, and perhaps introduce
+> record wrappers, which would then imply changing lots of package-body
+> code that will now need an extra level of selection.  This is exactly
+> the kind of change that people hate having to do, when all they want
+> is to be able to use "object.op()" notation with their private type.
+
+I totally agree, but I disagree with the idea that every package needs to have
+this done.
+
+Object.Op() is a privilege, not a right, and it should be allowed only for ADTs
+that were designed to be readable when it is used. It most certainly should not
+be allowed for every type, since if you use it at all, you need to use it pretty
+much exclusively (both to avoid confusion when reading, and also to gain the
+benefit of not needing a "use" clause).
+
+For instance, Text_IO is a package that should not allow Object.Op(). Many of
+the most commonly used operations can never be used in this form (the parameters
+aren't right), and if you have to have a "use" clause anyway, then use the
+traditional form of call everywhere to clarify what you are doing.
+
+I'd never want to see something like:
+
+     use Ada.Text_IO;
+     Some_File : File_Type;
+     ...
+ begin
+     ...
+     Some_File.Get_Line (Buffer, Len);
+     if Input_Trace then
+         Put_Line ("Line " & Line_Counter'Image & " has length " & Len'Image);
+     end if;
+
+because now you have all of the readability problems of a use clause AND all of
+the readability problems of Object.Op() munged together. And I don't think
+anyone is going to write:
+
+     Some_File : Ada.Text_IO.File_Type;
+     ...
+ begin
+     ...
+     Some_File.Get_Line (Buffer, Len);
+     if Input_Trace then
+         Ada.Text_IO.Current_Output.Put_Line (
+             "Line " & Line_Counter'Image & " has length " & Len'Image);
+     end if;
+
+to avoid the confusion. :-)
+
+Ergo, whether Object.Op() is even a good idea is a package-by-package decision.
+No one should be adding that willy-nilly to every package. It only makes sense
+for OOP-like ADTs. And I find it unlikely that any package for which it is a
+good idea would need any wrapping -- I don't believe I've completed a private
+type with a non-record type outside of ACATS tests ever (ultimately -- I've
+tried a number of times, but that just ended up making me work when I had to
+make it into a record).
+
+****************************************************************
+
+From: Emmanuel Briot
+Sent: Tuesday, October 29, 2019  3:14 AM
+
+I agree with Randy that this feature only needs to apply to record types. There
+is in practice no cost in performance when wrapping a type inside a record. It
+is more work (and perhaps not obvious to beginners) how to do that with
+indefinite type (unbounded arrays or records with discriminants), but it can be
+done.
+
+Compared to the current state of things (where one would add "tagged"), it
+doesn't add a whole lot, except:
+   1 - avoids the extra memory needed to store the tag in each instance
+   2 - doesn't let users extend the record type
+
+Extra memory usage
+================
+
+As for requiring an additional keyword to make that possible, as in:
+
+    type A is record private;
+
+that reminded of C++, where classes do not necessarily get a virtual table
+pointer. If the compiler can determine that table will not be needed, it doesn’t
+have to reserve space for it in class instances. I believe one of the cases
+where this optimisation is possible is:   no virtual method, no inherited
+virtual method.
+
+It perhaps could be done similarly in Ada. The user would write what we already
+do:
+
+   type A is tagged private;
+
+At that point, the current version of the standard already allows dot notation
+for subprogram calls, so there’s nothing to change.
+
+Upon seeing the full view of the object, the compiler could then decide whether
+or not it needs to add the tag. I am far from being a language lawyer, but can
+we imagine something like:
+
+    - no primtiive operations (only class-wide operations)
+      This is a bit restrictive possibly, in particular for functions returning
+      the type since they would now return a class-wide and thus use secondary
+      stack maybe
+
+    - no stream operations
+
+    - no Ada.Tags operations on the tag (external_tag,…) Those might be hard to
+      check, since they might occur in other packages.
+
+Because of the third point above, we would likely need the type to have a pragma
+similar to GNAT's
+
+     pragma No_Tagged_Streams (Type);
+
+and perhaps
+
+    pragma Discard_Names;
+
+Basically I am proposing to change this new feature request into an optimization
+problem.
+
+No type extension
+==============
+
+I believe there are already proposals for a “final” keyword or some such for Ada
+202x, so that making “tagged” publicly visible doesn’t necessarily mean users
+can extend the type.
+
+This is an independent feature which seems to have its own merits in terms of
+describing an API
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, October 29, 2019  11:46 AM
+
+...
+> At that point, the current version of the standard already allows dot
+> notation for subprogram calls, so there's nothing to change.
+>
+> Upon seeing the full view of the object, the compiler could then
+> decide whether or not it needs to add the tag. I am far from being a
+> language lawyer, but can we imagine something like:
+>
+>     - no primtiive operations (only class-wide operations)
+>       This is a bit restrictive possibly, in particular for functions
+>       returning the type since
+>       they would now return a class-wide and thus use secondary stack maybe
+
+This would seem to defeat the purpose of allowing Object.Op() notation. (The
+class-wide thing is rather a hack, IMHO, even if it was originally my idea. :-)
+And I don't see why any such restriction would be needed (presuming some sort of
+"final", it can't work otherwise as dispatching is always possible in that case
+in any existing class-wide operations - that might not even exist yet).
+
+>     - no stream operations
+>
+>     - no Ada.Tags operations on the tag (external_tag,.) Those might
+> be hard to check,
+>       since they might occur in other packages.
+>
+> Because of the third point above, we would likely need the type to
+> have a pragma similar to GNAT's
+>
+>      pragma No_Tagged_Streams (Type);
+>
+> and perhaps
+>
+>     pragma Discard_Names;
+
+Wouldn't it simply make more sense to just give an aspect No_Tag on the type and
+then enforce some restrictions on the use? Or, perhaps just make it a different
+keyword, like say "record"?? ;-)
+
+Isn't the GNAT pragma a global thing? It doesn't seem to make sense otherwise
+(the overhead is in Ada.Tags for the lookup table, not the type, other than the
+type name which is covered by Discard_Names). One would want to declare that one
+is not going to use Ada.Tags.Internal_Name and friends at all, 'cause that's
+what's expensive, not so much having a single type using it.
+
+> Basically I am proposing to change this new feature request into an
+> optimization problem.
+
+I don't think it works without throwing out the baby with the bathwater. And one
+needs "final" (see below).
+
+> No type extension
+> ==============
+>
+> I believe there are already proposals for a "final" keyword or some
+> such for Ada 202x, so that making "tagged" publicly visible doesn't
+> necessarily mean users can extend the type.
+>
+> This is an independent feature which seems to have its own merits in
+> terms of describing an API
+
+I can't find any such proposal that was ever formally presented to the ARG. I
+think it has come up occassionally in conversation, but most such conversation
+has considered it as having minimal value.
+
+Certainly, we'd need a full proposal that explained the "merits in terms of
+describing an API", since it seems to be the height of hubris to assume that you
+(an API designer) knows how clients are going to use your libraries. Ideally, an
+API would be designed to give the client maximum flexibility (which means
+allowing extension, avoiding visible access types, allowing clients to compose
+or allocate or use in a container as needs, etc.).
+
+The primary use seems to be to prevent users from extending API
+designs/implementations that don't work properly with extensions -- but that
+seems to be a problem with the API (and in some cases, the Ada language) more
+than any sort of good design.
+
+Anyway, there is no "final" proposal on the table, nor has there ever been one
+presented this cycle so far as I can tell, so that would have to be defined in
+order to make your idea even remotely viable. But that would be pretty similar
+to the proposal to use a new keyword (since you wouldn't get Object.Op() on an
+existing library with an untagged private type without modifying the spec to use
+"tagged final" or whatever syntax is decided -- it would be essentially the same
+as "record private", just with more complications). Not sure there is much gain
+for Object.Op() specifically (ignoring the merits or lack thereof for "final").
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, October 30, 2019  12:55 AM
+
+> Pretty much every time that I started out making a private type
+> something other than a record, I had to ultimately change it to a record.
+
+I almost agree. "Almost", since the full type is sometimes an array of (hidden
+in private part) records
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Wednesday, October 30, 2019  4:14 AM
+
+> Perhaps, but it introduces a very nasty need to go back and add
+> "record" to hundreds of existing private types on the off chance
+> someone will want to use object.op() notation, and perhaps introduce
+> record wrappers, which would then imply changing lots of package-body
+> code that will now need an extra level of selection.  This is exactly
+> the kind of change that people hate having to do, when all they want
+> is to be able to use "object.op()" notation with their private type.
+
+Hmmm... Everytime you write a reusable component, you have to make assumptions
+about how it will be used. For example, the choice of your identifiers depends
+on whether you assume users will have a use clause or not.
+
+Which makes me think of another possibility: allow prefix notation for
+(primitive) operations of any type within the scope of a use type clause (for
+the type). So people would allow it selectively if they want to. And those
+people are likely to already have the use type clause.
+
+****************************************************************
+
+From: Christoph Grein
+Sent: Wednesday, October 30, 2019  6:42 AM
+
+> Which makes me think of another possibility: allow prefix notation for
+> (primitive) operations of any type within the scope of a use type
+> clause (for the type). So people would allow it selectively if they
+> want to. And those people are likely to already have the use type clause.
+
+I := I."+"(2);
+
+or even
+
+I:=@."+"(2);
+
+Isn't this of utmost beauty? ;-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 30, 2019  9:18 AM
+
+> Which makes me think of another possibility: allow prefix notation for
+> (primitive) operations of any type within the scope of a use type
+> clause (for the type). So people would allow it selectively if they want to.
+> And those people are likely to already have the use type clause.
+
+A "use type" is not currently required to use object.op notation for tagged
+types.  The main point of this proposal, at least in my mind, is that something
+that is allowed on a tagged private type should also be allowed on an untagged
+private type.  That is, you shouldn't have to add "tagged" just to get to use a
+feature that really has little to do with being tagged.
+
+As far as other comments, I don't understand the comment that some private types
+should allow this and others shouldn't.  Almost by definition, a private type is
+an abstract data type, and hence it would seem that forcing users to distinguish
+between private types that allow object.op() and those that don't is an odd
+distinction to make.
+
+As far as what proportion of private types are completed with what sort of full
+types, here are two separate examples:
+
+ParaSail:
+31 private types (ignoring 14 formal private types)
+  full types:
+12 untagged record types
+12 access types
+4 derived types (typically derived from a private type exported by a
+                 generic instance)
+2 protected types
+1 tagged record type
+
+CodePeer/Utils:
+51 private types (ignoring 123 formal private types)
+  full types:
+23 derived types (often from a type exported by a generic instance)
+16 untagged record types
+7 access types
+5 tagged record types
+
+---
+
+I would add to the original goal that the source code for the package defining
+the private type should *not* have to be changed to allow object.op notation,
+and that removing or adding "tagged" to a private type should have no effect on
+the clients w.r.t. this object.op feature (presuming this addition or removal of
+"tagged" is otherwise legal).
+
+One further way to reduce the issue with ambiguity w.r.t. private types
+completed with access types is to limit this to primitive operations declared in
+the package spec -- disallowing use with so-called "late" primitives declared in
+the package body.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, October 30, 2019  2:22 PM
+
+...
+> As far as what proportion of private types are completed with what
+> sort of full types, here are two separate examples:
+>
+> ParaSail:
+> 31 private types (ignoring 14 formal private types)
+>   full types:
+> 12 untagged record types
+> 12 access types
+> 4 derived types (typically derived from a private type exported by a
+> generic instance)
+> 2 protected types
+> 1 tagged record type
+>
+> CodePeer/Utils:
+> 51 private types (ignoring 123 formal private types)
+>   full types:
+> 23 derived types (often from a type exported by a generic instance)
+> 16 untagged record types
+> 7 access types
+> 5 tagged record types
+
+Interesting. How do you deal with the need to free the memory associated with
+private access types when the objects are destroyed? That almost always forces
+me to use a controlled record type with a private type, even if the primary data
+is an aceess value.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, October 30, 2019  2:41 PM
+
+...
+> A "use type" is not currently required to use object.op notation for
+> tagged types.
+
+Agreed, and requiring it would defeat the primary purpose of allowing this in
+the first place, eliminating the need for use clauses in many cases.
+
+...
+> The main point of this proposal,
+> at least in my mind, is that something that is allowed on a tagged
+> private type should also be allowed on an untagged private type.  That
+> is, you shouldn't have to add "tagged"
+> just to get to use a feature that really has little to do with being
+> tagged.
+
+Agreed, but you should need to add *something*. (And it's probably a mistake for
+this to be allowed for all tagged types, but too late to fix.)
+
+> As far as other comments, I don't understand the comment that some
+> private types should allow this and others shouldn't.
+> Almost by definition, a private type is an abstract data type, and
+> hence it would seem that forcing users to distinguish between private
+> types that allow object.op() and those that don't is an odd
+> distinction to make.
+
+Definitely not true. A private type is just private; it might not be an ADT
+itself but rather a helper for some other ADT. A container cursor is a private
+type, but no one should think of it as an ADT (and I don't think it makes sense
+to use Object.Op() notation with it for that reason). Certainly, in any case
+where a package has multiple private types, only one of them can be the ADT
+(they all can't be the first parameter of subprograms!).
+
+I wonder if most of the private types completed with access types in your list
+are a form of reference (like a cursor) rather than an ADT, because memory
+management of ADTs made out of bare cursors is impossible. (See my other query.)
+In such a case, most subprograms using them won't be usable with Object.Op()
+notation anyway [wrong parameter position], a use clause would be inevitable
+(unless of course the *real** ADT allows Object.Op()).
+
+
+Aside: Ada does not have good support for the case where an ADT has various
+ancillary private types, as such types need to be derived/extended as a group.
+I've figured out a workable solution for that (after years of trying), but the
+ARG decided not to consider the probem further this go-round. Too bad, but
+understandable.
+
+If you care, the solution involves treating a pair (or more) of tagged types as
+a single entity for the purposes of dispatching and derivation. If anyone is
+interested, I can explain further.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, October 30, 2019  3:06 PM
+
+> Interesting. How do you deal with the need to free the memory
+> associated with private access types when the objects are destroyed?
+
+I don't know about ParaSail, but CodePeer allocates most heap memory in
+"subpools".  These are not the subpools in Ada -- Ada hijacked the name to mean
+something different. The CodePeer subpools have the property that all memory is
+freed when the subpool is finalized.  That means that individual objects in
+subpools need not be freed.
+
+(Later):
+
+> If you care, the solution involves treating a pair (or more) of tagged
+> types as a single entity for the purposes of dispatching and
+> derivation. If anyone is interested, I can explain further.
+
+I had a similar idea some years ago.  I've never worked out the details.  Didn't
+you write up an AI on that?  A reference to the AI would be good, or if that
+doesn't exist, I'd be interested in you explaining further.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 30, 2019  3:24 PM
+
+Here are the details on some of the access types used in the ParaSail front end:
+
+   type Reclamation_Info_Ptr is access all Reclamation_Info_Record;
+      --  this points to a table of pointers that is within a larger heap object
+      --  that is recovered "en masse" on leaving the scope.
+
+   type Stg_Rgn_Manager_Ptr is access Stg_Rgn_Manager_Type;
+      --  These are not reclaimed, but rather there is a free list and they
+      --  get reused that way
+
+   type Hash_Table is access Hash_Table_Rec;
+      --  There are explicit operations:
+         generic
+            with procedure Action (Key : Key_Type; Elem : Element_Type);
+         procedure Iterate_And_Remove (Table : in out Hash_Table);
+         --  Iterate over the table and remove each entry.
+         --  Reclaim the storage occupied by the table.
+
+         procedure Reclaim (Table : in out Hash_Table);
+         --  Reclaim the storage occupied by the table.
+         --  Leave the table empty.
+
+   type Pair_Ref is access all Hash_Table_Entry;
+        --  This is a short-lived type returned by a lookup routine, which in turn provides access
+        --  to two other short-lived refs:
+         function Key (Pair : Pair_Ref) return Key_Ref;
+         --  Return R/O reference to key of pair
+
+         function Element (Pair : Pair_Ref) return Element_Ref;
+         --  Return R/W reference to element of pair
+
+   type Read_Write_Mapping is access Read_Write_Mapping_Rec;
+       --  These are explicitly managed
+
+   type U_String is access U_String_Rec;
+       --  These are used to point into a string table that is used by the lexer
+       --  and grows as needed when new strings are seen, but never shrinks.
+
+So bottom line is that there are many different strategies used.  Clearly
+different situations call for different approaches.  I would claim that most if
+not all of the above are reasonable, and I would imagine that the universe of
+Ada programmers would have many many more situations where they have chosen, and
+will continue to choose, to implement private types as access types.  I really
+don't think we should be in the business of trying to force this to change.
+
+This seems completely orthogonal with allowing the use of object.op().  Having
+to change the package that defines the private type to allow the object.op()
+notation seems inappropriate.  We certainly aren't forcing anyone to use it, so
+presumably programmers will use it where it is appropriate, where their project
+encourages it, or on every third Tuesday, should they so choose.  I have heard
+many folks requesting that we don't tie this ability to a type being tagged, and
+it seems just as bad to tie it to how a private type is implemented.
+
+I would be interested in seeing cases where there is problematic ambiguity
+introduced by simply allowing this notation on all private types, and on their
+"full" types, when calling the primitive operations of the type that are defined
+in the package spec.  This seems to be the simplest rule, and from what I can
+tell, the chance of new ambiguity is very small.
+
+Certainly for those those who choose to never use access types to implement
+their private types, they won't have to worry about the problem!  And for those
+that do, based on the anecdotal bit of research I have done, they won't run into
+the problem at all.  The only place they could run into the problem are places
+where they have visibility on the full type, and if that becomes a big burden,
+well they can introduce a wrapper without altering the view seen by clients.
+But *requiring* them to introduce such a wrapper when there is no problem to
+begin with, seems diabolical... ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, October 30, 2019  4:19 PM
+
+[List of uses.]
+
+I'd argue that most of those aren't ADTs in the conventional sense and probably shouldn't be [and most likely can't be] using Object.Op() notation.
+Allowing it for use in a few cases seems bad for readability of Ada code.
+
+But I don't think there is much point in further discussion on this particular
+point, as it's unlikely that we'll agree.
+
+...
+> I would be interested in seeing cases where there is problematic
+> ambiguity introduced by simply allowing this notation on all private
+> types, and on their "full" types, when calling the primitive
+> operations of the type that are defined in the package spec.  This
+> seems to be the simplest rule, and from what I can tell, the chance of
+> new ambiguity is very small.
+>
+> Certainly for those those who choose to never use access types to
+> implement their private types, they won't have to worry about the
+> problem!  And for those that do, based on the anecdotal bit of
+> research I have done, they won't run into the problem at all.  The
+> only place they could run into the problem are places where they have
+> visibility on the full type, and if that becomes a big burden, well
+> they can introduce a wrapper without altering the view seen by
+> clients.  But *requiring* them to introduce such a wrapper when there
+> is no problem to begin with, seems diabolical... ;-)
+
+This problem never was a usage problem (so far as I know), but rather a language
+definition and implementation problem. The issue is that there is an infinite
+number of possible implicit dereferences/'Access insertions if one allows access
+types, and that isn't practically implementable. There has to be some
+restriction on it to make it implementable.
+
+I don't see that tying this to private types solves anything for the language
+definition and implementation. After all, you can add a partial view to any type
+by introducing a nested package, so every possibility exists (perhaps only in
+ACATS tests, but the language definition and implementations both have to cover
+all of the possibilities). You have all of the costs (essentially infinite for
+some compiler designs; a compiler would have to introduce an artificial limit on
+nesting) and you would be preventing people from using the notation in the most
+likely cases. There doesn't seem to be any difference from introducing partial
+views to the mix; you would get the same semantics from simply saying that it
+only works on primitive operations (for any type) -- which I think has been the
+only proposal from the beginning of time.
+
+So I think you either have to allow it everywhere, or only allow it for types
+that are specifically marked to allow it (tagged serves this purpose today).
+
+I think there are many arguments against allowing it generally: it harms
+readability (especially when mixed with other notation) - see Christophe's mail
+for a few examples, the implementation and language definitional complexity is
+quite high, and it seems abusive of the original Simula idea.
+
+To fix the language definitional issues, you have to reign in the implicit
+dereference and implicit 'Access cases (best to eliminate 'Access altogether and
+only allow a single dereference), but that would be a wart and difference
+compared to the tagged case. I suppose you could combine that with the partial
+view rule for non-record types, but now you have a three sets of rules (tagged
+types, untagged record types, untagged private type s) that are all subtly
+different.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, October 30, 2019  4:26 PM
+
+> ...  Having to change the package that defines the private type to
+> allow the object.op() notation seems inappropriate.
+
+I'm with Tucker on that one.  Prefix notation is not some dangerous thing that
+needs syntax along the lines of "Warning, Will Robinson!  I'm putting on my
+HAZMAT suit so I can use prefix notation."  ;-)  Just use it wherever you see
+fit.
+
+As I said, I'd prefer not to fix the problem under discussion at all, but if
+we're going to fix it, I agree with Tucker's approach.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 30, 2019  4:28 PM
+
+> This problem never was a usage problem (so far as I know), but rather a
+> language definition and implementation problem. The issue is that there is
+> an infinite number of possible implicit dereferences/'Access insertions if
+> one allows access types, and that isn't practically implementable. There has
+> to be some restriction on it to make it implementable. ...
+
+I'd like to see some concrete examples.  I really don't understand the problem
+you are describing.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, October 30, 2019  4:46 PM
+
+It's in the minutes and/or e-mail discussion (I think it was covered at a
+meeting, so it should be in the minutes) of the original Object.Op() proposal.
+The AIs in question are AI95-0252-1 and AI95-0407-1. You can use the fancy
+"voting" index to find the discussions.
+
+I note from reading 407 itself that Y.P when Y is an access value and P has an
+access parameter is actually interpreted as "Y.all'Access". Some Tucker Taft guy
+made that statement in e-mail. I suspect that is the crux of the problem.
+
+If you're still confused next week, I can do the research then, but I don't have
+time now and I expect to be gone the rest of the week.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, October 30, 2019  4:50 PM
+
+> I'm with Tucker on that one.  Prefix notation is not some dangerous
+> thing that needs syntax along the lines of "Warning, Will Robinson!
+> I'm putting on my HAZMAT suit so I can use prefix notation."  ;-)
+> Just use it wherever you see fit.
+
+That's nasty, because it leads to all kinds of nonsense. But if we are going to
+take that approach, then there is no reason to restrict it to private types (why
+should private types be special???).
+
+> As I said, I'd prefer not to fix the problem under discussion at all,
+> but if we're going to fix it, I agree with Tucker's approach.
+
+I don't, because Tucker's approach fixes none of the real problems we had with
+access Object.Op, and simply requires people to put a private type on anything
+they want to use with Object.Op(). If we are going to do it at all, it either
+has to be restricted to record types (always) or allowed generally. I don't
+think private types per-se have anything to do with it.
+
+I'm rapidly moving to your primary position of doing nothing, because the
+alternative is too much.
+
+****************************************************************
+
+From: John Barnes
+Sent: Wednesday, October 30, 2019  5:17 PM
+
+Having followed this discussion, I would do nothing.  I fear having to explain
+curious stuff when I update my book.
+
+****************************************************************
+
+From: Jeffery R. Carter
+Sent: Wednesday, October 30, 2019  3:49 PM
+
+> ...
+>> As far as what proportion of private types are completed with what
+>> sort of full types, here are two separate examples:
+>>
+>> ParaSail:
+>> 31 private types (ignoring 14 formal private types)
+>>   full types:
+>> 12 untagged record types
+>> 12 access types
+>> 4 derived types (typically derived from a private type exported by a
+>> generic instance)
+>> 2 protected types
+>> 1 tagged record type
+
+13 out of 31 (41.9%) have full types that are record types.
+
+>> CodePeer/Utils:
+>> 51 private types (ignoring 123 formal private types)
+>>   full types:
+>> 23 derived types (often from a type exported by a generic instance)
+>> 16 untagged record types
+>> 7 access types
+>> 5 tagged record types
+
+21 out of 51 (41.2%)
+
+PragmAda Reusable Components:
+28 non-formal private types of which 13 are visibly tagged (only to allow
+  Object.Operation notation) Of the remaining 15:
+1 modular type
+3 extend Ada.Finalization.[Limited_]Controlled
+9 untagged record types
+2 derived from an untagged private type that is one of the 9 above
+
+So 25 of 28 (89.3%)
+
+Not surprising since many of the components are ADTs.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 30, 2019  8:37 PM
+
+I looked at the AIs and the minutes, and didn't find anything more concrete that
+there were complexities associated with supporting this on untagged types, and
+we felt that tagged types were the most important, so we focused on those.
+
+I believe time has shown that programmers like object.op() notation enough that
+they will make a type tagged merely to allow for this notation.  I think even in
+the ARG we have periodically said that we want a private type to be tagged not
+so it can support extension, but rather so that it will support object.op()
+notation.  We have had at least one suggestion to make Unbounded_Strings tagged
+for this same reason.
+
+To me the primary justification for this change comes from private types where
+there really is no reason to make them tagged except to provide object.op()
+notation.
+
+In any case, I'll create some concrete examples to try to suss out what might be
+the implementation or usability issues.  Without such examples I am struggling
+to see the problem.
+
+****************************************************************
+
+From: Egil Harald Hoevik
+Sent: Thursday, October 31, 2019  4:42 AM
+
+First of all, add me to the "do nothing"-camp.
+
+However, if this is going to be "fixed", why does it have to be a property of
+the type? Can it be part of the visibility instead? We're already used to
+controlling visibility based on what we need from a type with a use_type_clause,
+like the following
+
+-- make primitive operators visible
+declare
+   use type Ada.Strings.Unbounded.Unbounded_String;
+   Foo, Foobar, Foobaz : Ada.Strings.Unbounded.Unbounded_String;
+begin
+   Foo := Ada.Strings.Unbounded.To_Unbounded_String("foo");
+   Foobar := Foo & "bar"; -- primitive operator visible
+   Foobaz := Ada.Strings.Unbounded.Append(Foo, "baz"); end;
+
+-- make all primitive operations visible in addition to operators declare
+   use all type Ada.Strings.Unbounded.Unbounded_String;
+   Foo, Foobar, Foobaz : Ada.Strings.Unbounded.Unbounded_String;
+begin
+   Foo := To_Unbounded_String("foo"); -- primitive operations visible
+   Foobar := Foo & "bar";
+   Foobaz := Append(Foo, "baz"); -- primitive operations visible
+end;
+
+
+As far as I can tell (and I believe RM/AIs state as much), the above "use all
+type" already makes everything visible that's needed  for prefix notation, so
+why not just piggy-back on that feature? Something along these lines:
+
+-- allow prefix notation
+declare
+   use all type Ada.Strings.Unbounded.Unbounded_String with Prefix_Notation;
+   Foo, Foobar, Foobaz : Ada.Strings.Unbounded.Unbounded_String;
+begin
+   Foo := To_Unbounded_String("foo");
+   Foobar := Foo & "bar";
+   Foobaz := Foo.Append("baz"); -- prefix notation
+end;
+
+
+Now, I am not a compiler writer, so I probably don't see all the problems
+associated with this solution, but I thought I'd throw it out there...
+
+In any case, I'm in the "do nothing"-camp, and I believe the co-derivation
+problem would be a far more usable thing to spend time on, especially when there
+already seems to exist an actual implementable solution
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Thursday, October 31, 2019  4:57 AM
+
+> As far as I can tell (and I believe RM/AIs state as much), the above
+> "use all type" already makes everything visible that's needed  for
+> prefix notation, so why not just piggy-back on  that feature?
+
+<tongue_in_cheek>
+Because the proponents of this proposal want to have the benefits of a use
+clause without having to write a use clause, 'cause use clauses are evil
+(only if explicitely written).
+</tongue_in_cheek>
+
+****************************************************************
+
+From: Richard Wai
+Sent: Thursday, October 31, 2019  12:46 PM
+
+Would we not perhapse just be able to modify 4.1.3 like this:
+
+9.1/2: " view of a subprogram whose first formal parameter is of [a tagged]
+{any} type or is an access parameter whose designated type is tagged:"
+
+9.2/3: "The prefix [(after any implicit dereference)] shall resolve to denote an
+object or value of {any type} [specific tagged type] T] or class-wide tagged
+type T'Class. {If prefix denotes a view of an access type, the view shall be an
+access to a tagged type or class-wide tagged type}. The selector_name shall
+resolve to denote a view of a subprogram declared immediately within the
+declarative region in which an ancestor of the type T is declared. The first
+formal parameter of the subprogram shall be of type T, or a class-wide type that
+covers T, or an access parameter designating one of these types. The designator
+of the subprogram shall not be the same as that of a component of the tagged
+type visible at the point of the selected_component. The subprogram shall not be
+an implicitly declared primitive operation of type T that overrides an inherited
+subprogram implemented by an entry or protected subprogram visible at the point
+of the selected_component. The selected_component denotes a view of this
+subprogram that omits the first formal parameter. This view is called a prefixed
+view of the subprogram, and the prefix of the selected_component (after any
+implicit dereference) is called the prefix of the prefixed view."
+
+This avoids issues with implicit dereferencing, while also allowing for private
+types completed as access types. This would probably require prefixed calls in
+private part/body of the implementing package to use "Object.all.Operation", but
+I think this would be rare enough to not really be much of a burden.
+
+This approach would also bring with it the bennefits of not always having to use
+"use". I think readability is not much harmed by this since A) this already
+happens with tagged types, and B) the behaviour is simple and obvious, so one
+knows where to look to find these operations since the type itself either
+directly specifies the package it is defined in, or that is visable via "use" or
+a subtype declaration.
+
+I'd imagine that implementation would not be terribly hard, either.
+
+I generally agree this would be well-received, and is probably worth pursuing,
+however if it involves new syntax or reserved words, I think it would be far too
+disruptive to be worth it.
+
+One other much simpler idea I had was to possibly intruduce an aspect for tagged
+types, such as perhapse "Static" which, if true, disallows extension or
+dispatching calls. It would be for those who want the prefixed notation of
+tagged types, without any of the run-time implications or OOP features.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October 31, 2019  2:12 PM
+
+I'll have to look at your wording in more detail to understand the implications.
+
+I don't see that the notion of a "static" tagged type addresses the same issue,
+since there is a lot of existing code where the notation would be useful.  And
+in what sense does the phrase "static tagged" suggest "object.op()" notation?
+
+If we wanted to be excruciatingly explicit we could have "with
+Allow_Prefixed_Calls => True", but since you don't need to do that for tagged
+private, it seems odd to require it for untagged private.
+
+In any case, I'll look at your wording suggestion.  I would rather have an
+"English" non-lawyerly explanation of the rule before we get too deep into the
+RM wording (and we were going to move back to the ARG mailing list for detailed
+wording debates... ;-).
+
+****************************************************************
+
+From: Richard Wai
+Sent: Thursday, October 31, 2019  2:24 PM
+
+> I'll have to look at your wording in more detail to understand the
+> implications.
+>
+> I don't see that the notion of a "static" tagged type addresses the
+> same issue, since there is a lot of existing code where the notation
+> would be useful.  And in what sense does the phrase "static tagged"
+> suggest "object.op()" notation?
+
+The idea here was more about avoiding the implications of using tagged types
+just to get the object.op functionality - i.e. being able to do this is
+situations where dynamic dispatching would be disallowed or unwanted.
+
+> If we wanted to be excruciatingly explicit we could have "with
+> Allow_Prefixed_Calls => True", but since you don't need to do that for
+> tagged private, it seems odd to require it for untagged private.
+>
+> In any case, I'll look at your wording suggestion.  I would rather
+> have an "English" non-lawyerly explanation of the rule before we get
+> too deep into the RM wording (and we were going to move back to the
+> ARG mailing list for detailed wording debates... ;-).
+
+Fair enough! The basic idea is that selected components can resolve to a view of
+a subprogram for any type, not just tagged types, except for access types, which
+can only resolve to a view of a subprogram if they denote any tagged type.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October 31, 2019  2:48 PM
+
+A goal is to avoid having to switch notation when you move a piece of code from
+a place where it can only see the private type, to a place where it can see the
+full type.  This comes up in things like default expressions of subprograms,
+since they generally appear both in the visible part of a package as well as at
+the point of the body.  Alternatively, you might have a piece of code that was
+in an external package, and you decide to make the package into a child package,
+and suddenly its body might now have visibility on the full definition of some
+private type defined in its parent package.  This is why one of our "design
+principles" is that anything you can do on the partial view of a type you should
+be able to do also on the full view.
+
+I have yet to find a serious problem with access types that are used to
+implement a private type.  I hope to provide some examples shortly to help
+understand the issue better...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October 31, 2019  3:28 PM
+
+So here is an example, produced by simplifying a Vector abstraction in the
+ParaSail front end:
+
+generic
+   type Element_Type is private;
+package PSC.Vectors is
+
+   --  Extensible Vector of elements
+
+   Max_Elem_Index : constant := 1_000_000;
+   --  Max number of elements in a vector
+
+   type Elem_Index is range 0 .. Max_Elem_Index;
+
+   No_Elem_Index : constant Elem_Index := 0;
+
+   type Vector is private;
+   --  Vector of elements
+
+   function Num_Elements (Vec : Vector) return Elem_Index;
+   --  Return number of Elements in Vec
+
+   procedure Add_Element
+     (Vec : in out Vector;
+      Elem : Element_Type;
+      Index : out Elem_Index);
+   --  Add Element to Vector and return its Index
+
+   function Nth_Element
+     (Vec : Vector;
+      Index : Elem_Index)
+      return Element_Type;
+   --  Retrieve Element at given index.
+
+   procedure Set_Nth_Element
+     (Vec : in out Vector;
+      Index : Elem_Index;
+      Elem : Element_Type);
+   --  Overwrite nth element.
+
+private
+
+   type Vector_Rec;  --  defined below
+   type Vector is access Vector_Rec;
+
+   type Element_Array is array (Positive range <>) of Element_Type;
+
+   type Vector_Array is array (Positive range <>) of Vector;
+   --  For large Vectors, we break them up into sub-Vecs
+
+   subtype Level_Range is Natural range 0 .. 3;
+   --  Level indicates number of number of levels of indirection.
+
+   type Vector_Rec (Level : Level_Range; Len : Natural) is
+   --
+   --  The single discriminant "Len" is being used
+   --  in two different ways:
+   --   If Level = 0, as the capacity of the Vec.
+   --   If Level > 0, as the number of Sub_Vecs.
+   record
+      Count : Natural := 0;
+      case Level is
+         when 0 =>
+            Elements : Element_Array (1 .. Len);
+         when others =>
+            Total_Capacity : Natural := 0;
+            Sub_Vecs : Vector_Array (1 .. Len);
+      end case;
+   end record;
+
+end PSC.Vectors;
+
+-----
+
+So, the question is where could problems arise, if we allow object.op() notation
+on the private type Vector, including in places where we can see that Vector is
+actually "access Vector_Rec"?
+
+So given "V : Vector" is there danger in allowing "object.op()" references such
+as "V.Num_Elements" or "V.Nth_Element(3)" in places where "ptr.component"
+references such as "V.Level" and "V.Elements(4)" are also legal, thanks to
+implicit dereference?  Or let us suppose that Vector_Rec is itself defined by
+deriving from another private type, meaning it might have a set of operations
+defined on that private type, in addition to potentially still having a visible
+discriminant such as Level.  Does this impose problems?
+
+Clearly there is overload resolution to be done.  We already have situations in
+Ada 2012 where the prefix of a prefixed view can be overloaded, such as when we
+have two overloaded functions that return different tagged types each with their
+own set of operations and components.  We can also have overloaded functions
+where one returns a tagged type T1 and one returns an access type designating a
+tagged type T2, and we have to resolve calls on operations using prefixed
+notation. That is, we might have F(...).Op1 where one F(...) might return T1 and
+another might return access T2, and we need to resolve the meaning(s) of Op1 in
+the two contexts.  There is already a "preference" for components over prefixed
+views in 4.1.3(9.2), and this could generalize directly to giving a preference
+to components of the designated type of an access type.
+
+The above seems to indicate to me that allowing object.op() notation on access
+types that implement a private type does not introduce any particularly new
+overloading situations, and the implementor of the private type can deal
+internally with any problems that they encounter in their own internal code that
+bumps into unresolvable ambiguities.  It is never a problem for code that only
+sees the private type, which is what the clients of the abstraction care about.
+
+If there really is an implementation problem, it would be helpful to try to
+express it based on the above example, or by showing another example that
+illustrates the problem.  I am having trouble finding one.
+
+****************************************************************
+
+From: Jeffrey R. Carter
+Sent: Friday, November 1, 2019  6:33 AM
+
+> First of all, add me to the "do nothing"-camp.
+
+The ARG has a history of rejecting proposals for which there is a workaround,
+even when, unlike this proposal, things are very straightforward. As there is
+a workaround for this (just make it visibly tagged), I expect the ARG to
+reject this proposal as well.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, November 4, 2019  1:31 PM
+
+>> First of all, add me to the "do nothing"-camp.
+>
+> The ARG has a history of rejecting proposals for which there is a
+> workaround, even when, unlike this proposal, things are very
+> straightforward. As there is a workaround for this (just make it
+> visibly tagged), I expect the ARG to reject this proposal as well.
+
+There are always workarounds, given that Ada 83 was pretty much Turing
+complete.
+
+The question is often more of balancing ease of use in a particular situation
+vs overall language complexity.  In a case like this, we are effectively
+simplifying the language, by removing a somewhat arbitrary restriction that
+Object.Op() only works with tagged types.
+
+****************************************************************
+
+From: Arnaud Charlet
+Sent: Tuesday, November 5, 2019  7:10 AM
+
+I like Randy's suggestion to a KISS approach where only record types get the
+object.operation (and private types marked record, which looks like a reasonable
+extension of the current tagged private).
+
+I disagree with Tuck on the requirement that this feature should require no code
+change: this isn't what we see in practice from  GNAT users: people who use the
+object.method notation are definitely willing to modify their code to do so,
+proof is that these people today are precisely modifying their code to add
+artificial 'tagged' to their record.
+
+I don't think we should worry about access types at all, yes you can come up
+with some real examples where having support for object.method on private access
+types would be useful, that doesn't mean we should complexify the language to
+allow it. After all object.method is a (very nice) convenience, and as I said
+above, people are definitely willing to modify their code to take advantage of
+this convenience, and in particular in the example you sent, wrapping the
+private access type into a record would work just fine.
+
+The Ada language is already complex enough, so let's be careful about
+introducing extra complexity only when it is necessary.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 5, 2019  12:34 PM
+
+> I like Randy's suggestion to a KISS approach where only record types
+> get the object.operation (and private types marked record, which looks
+> like a reasonable extension of the current tagged private).
+
+Adding a new form of syntax to reveal that the full type is a record type is not
+keeping it simple in my mind, particularly if the only reason to add "record" to
+the private type declaration is so you can use object.op() notation.  The
+original proposal required no syntax changes, and simply modified the wording of
+4.1.3(9.2/3) to remove some restrictions. ...
+
+****************************************************************
+
+From: Arnaud Charlet
+Sent: Tuesday, November 5, 2019  1:30 PM
+
+Well, so far I have understood Randy's proposal at first sight while I still do
+not understand your "original proposal", hence the fact that it's much more
+complex to grasp for users (and for implementers? Can't tell until I understand
+what you are proposing).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 5, 2019  7:06 PM
+
+> Adding a new form of syntax to reveal that the full type is a record
+> type is not keeping it simple in my mind, particularly if the only
+> reason to add "record" to the private type declaration is so you can
+> use object.op() notation.  The original proposal required no syntax
+> changes, and simply modified the wording of 4.1.3(9.2/3) to remove
+> some restrictions.
+> ...
+
+I don't think that works, at least not the way you have described it. The
+wording in question is:
+
+The prefix (after any implicit dereference) shall resolve to denote an object or
+value of a specific tagged type T or class-wide type T'Class. The selector_name
+shall resolve to denote a view of a subprogram declared immediately within the
+declarative region in which an ancestor of the type T is declared. The first
+formal parameter of the subprogram shall be of type T, or a class-wide type that
+covers T, or an access parameter designating one of these types. The designator
+of the subprogram shall not be the same as that of a component of the tagged
+type visible at the point of the selected_component. The subprogram shall not be
+an implicitly declared primitive operation of type T that overrides an inherited
+subprogram implemented by an entry or protected subprogram visible at the point
+of the selected_component. The selected_component denotes a view of this
+subprogram that omits the first formal parameter. This view is called a prefixed
+view of the subprogram, and the prefix of he selected_component (after any
+implicit dereference) is called the prefix of the prefixed view.
+
+If one just removes the "tagged" from the "specific tagged type T", now you have
+a lot of text talking about the "class-wide type T'Class" and "a class-wide type
+that covers T", which is nonsense for an untagged type. I think we'd have to
+have redo the wording to have separate wording for the T'Class case (or possibly
+for untagged types) in order for the wording to make real sense. (Every time
+I've tried to use wording that ignores issues like this, the group has required
+me to change it before we put it into the Standard. You don't get a pass on
+that.)
+
+I'm sure we can come up with wording to allow prefixed notation on all types,
+should we want to do that, but it's more complex than you are claiming.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 5, 2019  7:43 PM
+
+...
+> I have yet to find a serious problem with access types that are used
+> to implement a private type.  I hope to provide some examples shortly
+> to help understand the issue better...
+
+As previously noted, I see no value to restricting the use of access types to
+certain contexts; if we allow access types anywhere, all of the complications
+occur, so there is no reason to restrict the usage. It's all or nothing for
+access types.
+
+Here's some interesting points noted during my research:
+
+From AI-00252:
+
+We originally generalized this to support non-tagged types, but the added
+complexity this brought to handling access types seemed more than the
+anticipated benefit, since we would have to consider primitives of the access
+type itself as well as those of its designated type.
+
+---
+
+From the minutes of the 13th ARG meeting (Leuven, Belgium, May 2001):
+
+Erhard starts a full example, to better understand how access types work in this
+context:
+
+package P1 is
+   type T1 is ...
+   procedure Process (P : access T1);
+   type AT1 is access T1'Class;
+   procedure Process2 (P : AT1);
+end P1;
+
+with P1;
+package P2 is
+   type T2 is new P1.T1 with ...;
+   procedure Process (P : access T2);
+   type AT2 is access T2'Class;
+end P2;
+
+declare
+   Obj : At2;
+begin
+   Obj.Process;  -- This works.
+   Obj.Process2; -- This does not work. (Different access types.) end;
+
+[Randy's 2019 note: I note that the resolution of anonymous access parameters
+and parameters of named access types is wildly different if we allow prefixed
+views of access types; that's illustrated by this example. Yuck.]
+
+...
+
+Tucker jokes that we don't need infix notation at all if we have this
+notation: If A is an Integer, it becomes possible to write:
+
+   if A."-"."/="(3)."not" then ...
+
+[Translation: if not (-A /= 3) then...] Someone notes that we now can have
+obfuscated Ada contests, just like C-family languages. This closes the
+discussion with laughter.
+
+[Randy's 2019 note: Great. What happened to readability as a concern??]
+
+---
+
+From the minutes of the 14th ARG meeting (Columbia, Maryland, October 2001 [in a
+hotel we shared with the Dallas Cowboys, in the area to play the Ravens; I got
+run over by Jerry Jones' bodyguards when returning from dinner one night]):
+
+Why do we need this feature?
+
+Proponents say it eliminates the need for using the package name for the
+operations, which is an annoyance to many coming from other OOP languages. It
+could be more attractive to newcomers.
+
+Those opposed say is that you can get around this problem with use clauses.
+Can we afford the ARG time and implementation expense for this feature?
+
+A straw vote to continue work on this AI passes 6-3-1.
+
+Various simplifications are suggested. Erhard suggests not worrying about named
+access types. Tucker wonders if restricting this feature to just composite types
+would help. Erhard suggests going further and restricting it to tagged types.
+Does disallowing elementary and arrays as the prefix help? (That is, the prefix
+would be restricted to things for which dot already is allowed.) The group
+expresses lukewarm approval for this improvement.
+
+Bob worries that private completed by integer could use this notation outside
+the package, but not inside, which seems weird. It is left to Tucker to come up
+with a new proposal.
+
+[Randy's 2019 note: It appears from this that the restriction to tagged types
+only occurred mainly as an olive branch to those that didn't want to do it at
+all.]
+
+---
+
+From the minutes of the 19th ARG meeting (Toulouse, France, June 2003):
+
+...
+
+Jean-Pierre is concerned that this makes it harder to check that all subprograms
+are identified by a fully expanded name. In Ada 95, a search for use is
+sufficient to insure that, and that is very easy to find.
+
+Randy points out that the inheritance of OOP breaks this anyway -- the routine
+is often not (explicitly) declared in the package to which the expanded name
+refers. So this doesn't make it much harder to find the declaration (you have to
+search the same set of packages either way). Erhard says that this was even true
+in Ada 83 with derived type inheritance. Pascal suggests using an ASIS tool to
+check this (and other stylistic rules), not grep.
+
+Jean-Pierre is not convinced. He fears that high-integrity users might be
+alienated. Alan points out that high-integrity users don't use tagged anyway -
+they can grep for tagged if they want (and thus avoid this new feature
+completely).
+
+[Randy's 2019 note: expanding the notation to all types would definitely make it
+harder to avoid it for those that want to do that. Not sure if this is a real
+concern today (J-P's AdaControl tool probably can find all of these uses).]
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 5, 2019  9:23 PM
+
+...
+> I have yet to find a serious problem with access types that are used
+> to implement a private type.  I hope to provide some examples shortly
+> to help understand the issue better...
+
+My research and premise is described in my other note. I'm only considering the
+effects of allowing prefixed notation on all types (as opposed to only record
+types or the existing only tagged types) as there appears to be  no benefit to
+any additional complication.
+
+The current Ada 2012 rules requires the following tree for resolving selected
+notation when the prefix resolves to an object. (Note: This tree is for each
+such prefix resolution; a prefix can resolve to multiple things, but each one
+has to be resolved by this tree. Also note that I'm ignoring the "current
+instance" here; it is a type name but it is treated like an object for the
+purposes of resolution.) This tree makes explicit the resolution of implicit
+dereferences.
+
+For a prefix that is an object of specific type T or class-wide type
+T'Class:
+
+1) If T is a non-array composite type or an access to a non-array composite
+   type, then the selector can be a discriminant of T (or the designated type of
+   T).
+2) If T is a record type or an access to a record type, then the selector can be
+   a (regular) component of T (or the designated type of T).
+3) If T is a task or protected object, or an access to a task or protected
+   object, then the selector can be an entry or protected subprogram of T (or
+   the designated type of T).
+
+If any of the above work, do not try any prefixed views. [Aside: This isn't
+quite accurate for (3); not worth figuring out the exact rule here, it's not
+relevant to my point.]
+
+Let T-Ancestor be the set of declarative regions where an ancestor of T is
+declared, and T-Region be the (single) declarative region where T is declared.
+Then:
+
+4) If T is a tagged type, then the selector can be a subprogram with the first
+   parameter having type T or a classwide type that covers T declared in
+   T-Ancestor (Obj.Op(...)).
+5) If T is a tagged type, then the selector can be a subprogram with the first
+   parameter being an access parameter designating type T or of a classwide type
+   that covers T declared in T-Ancestor (Obj'Access.Op(...)).
+6) If T is an access to a tagged type TT, then the selector can be a subprogram
+   with the first parameter having type TT or a classwide type that covers TT
+   declared in TT-Ancestor (Obj.all.Op(...)).
+7) If T is an access to a tagged type TT, then the selector can be a subprogram
+   with the first parameter being an access parameter designating type TT or of
+   a classwide type that covers TT declared in TT-Ancestor
+   (Obj.all'Access.Op(...)).
+
+----
+
+Note that for any particular subprogram and type of object prefix, only one of 4
+through 7 is possible. This makes it possible to include information about the
+(only) possible prefixed view inside of the subprogram declaration in a compiler
+symbol table. I believe that information is crucial to providing an efficient
+implementation of prefixed views (certainly in Janus/Ada, can't say for sure
+about other implementations). It's too expensive to do a search for a type
+declaration in each scope to determine if the subprogram is declared in the
+right place.
+
+[Disclaimer: I haven't tried to implement prefixed views in Janus/Ada yet - it's
+possible the implementation I currently have in mind won't work for some reason.
+It's also possible that there is some other implementation that's better,
+although that's unlikely.]
+
+Note that for the case of a specific parameter type, we can use T-Region rather
+than T-Ancestor (no operation of type T can be declared in an ancestor's region,
+unless the ancestor's region is the same as T's region - which is not
+interesting). That's a simplification. Note that these rules do not require the
+operations to be primitive -- this matters for types declared in subprogram and
+blocks (new operations aren't primitive, but are still accessible via Obj.Op).
+None of this is particularly relevant to my point, but they do affect the
+implementation.
+
+Now, if we allow any type here, then we have to separate the class-wide rules
+from the other rules, giving something like:
+
+4) For any type T, then the selector can be a subprogram with the first
+   parameter having type T declared in T-Region (Obj.Op(...)).
+5) For any type T, then the selector can be a subprogram with the first
+   parameter being an access parameter designating type T declared in T-Region
+   (Obj'Access.Op(...)).
+6) If T is an access to a type TT, then the selector can be a subprogram with
+   the first parameter having type TT declared in TT-Region (Obj.all.Op(...)).
+7) If T is an access to a type TT, then the selector can be a subprogram with
+   the first parameter being an access parameter designating type TT declared in
+   TT-Region (Obj.all'Access.Op(...)).
+8) If T is a tagged type, then the selector can be a subprogram with the first
+   parameter having a classwide type that covers T declared in T-Ancestor
+   (Obj.Op(...)).
+9) If T is a tagged type, then the selector can be a subprogram with the first
+   parameter being an access parameter designating a classwide type that covers
+   T declared in T-Ancestor (Obj'Access.Op(...)).
+10) If T is an access to a tagged type TT, then the selector can be a subprogram
+    with the first parameter having a classwide type that covers TT declared in
+    TT-Ancestor (Obj.all.Op(...)).
+11) If T is an access to a tagged type TT, then the selector can be a subprogram
+    with the first parameter being an access parameter designating a classwide
+    type that covers TT declared in TT-Ancestor (Obj.all'Access.Op(...)).
+
+For non-access types, the same holds true: for any particular subprogram and
+type of object prefix, exactly one of these cases is possible.
+
+For access types, though, at least two of the cases is possible for a single
+subprogram (4 and 6 or 5 and 7). The good news is I can't find any way to have
+more than two possible, so it seems practical to retain the symbol table
+information.
+
+Note that this just makes the implementation semi-practical. It still would be
+many times more expensive than other resolution (I'd guess 5-50 times in usual
+cases, but that depends on how many declarations of the selector exist anywhere
+in the partition. For a selector like Next, the expense would be on the high
+end). I can't say if this is significant, as resolution is not noticeably
+expensive in Janus/Ada today, so it's possible that making it much slower on
+selected components will not matter. (And I note that this some of this expense
+occurs from allowing prefixed notation at all - allowing all types will clearly
+makes it worse but adding subprograms to the mix at all adds a lot of overhead
+to resolving selected components.)
+
+BTW, this is a new and different implementation approach. The original one would
+have been extremely expensive if access types were included, but it was very
+expensive even for tagged Obj.Op (only being practical because it didn't add
+cost to the vast majority of selected components - that wouldn't be true for
+this new approach but that doesn't matter since pretty much everything would
+allow it).
+
+Anyway, the bottom line here is that I don't think (assuming the *exact* set of
+rules I gave above) that the implementation of unrestricted Obj.Op is
+dangerously more expensive than the current rules.
+
+
+P.S. For future reference (mostly mine), the implementation I have in mind is
+essentially that for every interesting prefix, one has to look at the entire
+list of declarations with a particular defining identifier. Whether it makes
+sense to prune that list beforehand (which we do for other such lists using
+visibility -- which doesn't come into play here) is unclear. For many possible
+selectors, the pruned list and the entire list will be lengthy and identical
+(think any subprogram that exists in every container, like Next; a program using
+containers extensively could have dozens of instances and all of them would
+provide a candidate). As such, creating a separate pruned list might take longer
+than any time that could be saved. OTOH, because of overriding it's possible
+that there would be lots of irrelevant decls around for many selectors. Probably
+will have to test some of these cases to see which approach is better.
+
+Either way, each subprogram decl would need an indication of the kind of
+prefixed notation allowed (if any) and the associated type (there can be only
+one for each subprogram). Two such indications would be needed, one for direct
+use and one for implicit dereferences. These would be used to make testing
+whether a particular prefix could work relatively cheap (and if the possibles
+list is actually created, to eliminate items that can't work for any possible
+prefix). The alternative of searching through the containing scope to see if the
+type is also declared there would be crazy-expensive.
+
+The class-wide cases are more complex but follow the same pattern (the
+information would allow prefix notation if the type is that of any ancestor).
+
+Of course, one also has to figure out how to generalize the existing resolution
+of names to support the effectively shortened parameter list of a prefixed view.
+Currently, everything is tied to a subprogram declaration which presumably
+wouldn't exist (with the correct number of parameters) for a prefixed view.
+There is also going to be an issue figuring out in the later Check pass when to
+insert .all or 'Access or both.
+
+These latter factors is why it's going to take a lot of motivation to want to
+dig into this resolution code and related code to try to implement prefixed
+views.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 5, 2019  9:50 PM
+
+...
+> package P1 is
+>    type T1 is ...
+>    procedure Process (P : access T1);
+>    type AT1 is access T1'Class;
+>    procedure Process2 (P : AT1);
+> end P1;
+>
+> with P1;
+> package P2 is
+>    type T2 is new P1.T1 with ...;
+>    procedure Process (P : access T2);
+>    type AT2 is access T2'Class;
+> end P2;
+>
+> declare
+>    Obj : At2;
+> begin
+>    Obj.Process;  -- This works.
+>    Obj.Process2; -- This does not work. (Different access types.) end;
+>
+> [Randy's 2019 note: I note that the resolution of anonymous access
+> parameters and parameters of named access types is wildly different if
+> we allow prefixed views of access types; that's illustrated by this
+> example.
+> Yuck.]
+
+To expand on this a bit:
+
+Ada 2007 and Ada 2012 both added some implicit conversions for anonymous access
+types, so this effect already occurs with regular calls. For example, using the
+declarations above and assuming universal Obj.Op:
+
+declare
+    Obj2 : At2 := ...;
+begin
+    Obj2.Process;  -- OK. (Actually Obj2.all'Access.Process).
+    Obj2.Process2; -- Nope.
+                   -- Note: 'Access only tried for anonymous access params
+    Process (Obj2); -- OK.
+    Process2 (Obj2); -- Nope.
+end;
+
+However, the prefixed view rules aren't the same as the implicit conversion
+rules. So there are anomolies:
+
+with P1;
+package P3 is
+   type T3 is new P1.T1 with ..
+   procedure Process (P : access T3);
+   type GAT3 is access all T3'Class;
+   procedure Process3 (P : GAT3);
+end P3;
+
+declare
+    Obj3 : access P3.T3 := ...;
+begin
+    Obj3.Process;  -- OK. (Actually Obj3.all'Access.Process).
+    Obj3.Process3; -- Nope.
+    Process (Obj3); -- OK.
+    Process3 (Obj3); -- OK by 8.6(26.1/3)
+end;
+
+Note that there is no expected type in 4.1.3, so the implicit conversions of 8.6
+don't apply to prefixed views (and they would make some prefixes ambiguous if
+applied generally, so we don't want that).
+
+I think that there is also a difference with "covers", which goes mostly one way
+for 'Access but goes both ways for implicit conversions. That could cause a
+similar anomaly. The extra rules for discriminants for 'Access might also cause
+an anomoly; I didn't try to work out if that is possible or not.
+
+These are definitely possible to fix, but would add additional complication both
+for the language description and for implementations. And if we don't fix them,
+they'll cause complication for users due to the subtle differences. Yuck either
+way.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, November 6, 2019  7:15 AM
+
+Wow, lots of data!  Thanks, Randy, for assembling all of this.  It will take a
+while to study all of this.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, November 6, 2019  7:26 AM
+
+> Anyway, the bottom line here is that I don't think (assuming the
+> *exact* set of rules I gave above) that the implementation of
+> unrestricted Obj.Op is dangerously more expensive than the current rules.
+
+I am glad that your "bottom line" agrees with my much less in-depth sense of
+the situation.
+
+****************************************************************
+
+From: Raphael Amiard
+Sent: Wednesday, November 6, 2019  5:01 PM
+
+Personally I think object.op should be allowed on every type (even access types).
+Ambiguities should be signaled to the users by the compiler if/when they arise.
+
+I see no reason of restricting ourselves here, since Ada had the good taste of
+standardizing the notion of primitive operation since the first iteration of
+the language. What would be the arguments against that?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, November 6, 2019  5:39 PM
+
+>I see no reason of restricting ourselves here, since Ada had the good taste
+>of standardizing the notion of primitive operation since the first iteration
+>of the language. What would be the arguments against that?
+
+Not interested in arguing either way here, but I wanted to caution you that
+Obj.Op has little to do with primitive operations. Nothing in the Obj.Op rules
+ever talk about primitive operations, for instance, rather talking about the
+place where a subprogram is declared. (I didn't remember this until my research
+yesterday.)
+
+The difference is significant for a type declared in a declarative_part of a
+subprogram or a block: subprograms declared with the type are eligible for
+Obj.Op notation, but they are not primitive and are not inherited by the
+derivation of a descendant type.
+
+One effect of this is that a compiler implementation has to use different
+rules/data for determining whether a subprogram is primitive vs. whether it can
+be used in prefixed (Obj.Op) notation.
+
+As I noted in one of my messages yesterday, the rules for implicit conversions
+and for the resolution of a prefix also differ in subtle ways, so for a
+one-parameter procedure, Obj.Op might be legal and Op(Obj) not legal, or vice
+versa. I'd guess that these cases are quite minimal for tagged types, but they
+become more visible when one allows access types.
+
+Net effect: this is not as simple as it seems. (Either for the language
+definition, or for an implementation.) Which makes it come down to the normal
+allocation of resources question: is it worth the allocation of X hours of work
+to this issue rather than other issues?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, November 6, 2019  7:04 PM
+
+> Not interested in arguing either way here, but I wanted to caution you
+> that Obj.Op has little to do with primitive operations. Nothing in the
+> Obj.Op rules ever talk about primitive operations, for instance,
+> rather talking about the place where a subprogram is declared. (I
+> didn't remember this until my research yesterday.)
+
+That is a bit misleading.  If the type is declared in the visible part of a
+package, then it is synonymous with being primitive, when we are talking
+about untagged types (since they don't have class-wide versions).  Frankly,
+I would be happy to limit it to types declared in the visible part of a
+package, if untagged.  Going beyond that seems unnecessary, especially if
+it introduces any new complexity.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, November 6, 2019  7:50 PM
+
+The existing rules for tagged types have this effect (if a tagged type is
+declared somewhere other than a package), so an attempt to restrict it to only
+types declared in a package would be incompatible with the Ada 2012 definition.
+
+And, as Raphael said, it's hard to justify adding restrictions to the use of
+Obj.Op, especially if they are different from the tagged case for no particular
+reason. I don't see any significant implementation difficulty with the current
+definition, it just is *new* -- one can't reuse anything existing.
+
+I personally don't find this important enough for the work, but if we're going
+to do it, we should do it with as little restriction as possible: preferably so
+that Op (Obj) and Obj.Op both or neither will resolve (for an Obj that is not
+overloaded).
+
+****************************************************************
+
+From: Joey Fish
+Sent: Wednesday, November 6, 2019  7:24 PM
+
+I was reminded a bit about something Dmitry brings up from time to time:
+multiple-dispatch. It seems to me like there's a bit of overlap (with that idea,
+and dot-notation) as the Ada 2005 standard designated [implicitly] a
+distinguished parameter/result in a subprogram for Object.Operation syntax.
+
+While it would be decried as ugly and unuseful/verbose of something like
+
+  Function Operation( X : Type_1; Y : Type_2 ) return Type_3
+
+    with Distinguished_Parameter => Y;
+
+it could be used to indicate that Y_Thing.Operation (X_Thing) is how the
+subprogram's dot-notation is intended to be used; and if we ever DO implement
+multiple-dispatch, or multiple-dispatching parameters, it could also indicate a
+precedence. [I thought that there was a precedence issue with multiple-dispatch,
+but that might have actually been something on multiple-inheritance I'd read
+somewhere.]
+
+****************************************************************

Questions? Ask the ACAA Technical Agent