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

Differences between 1.2 and version 1.3
Log of other versions for file ai05s/ai05-0151-1.txt

--- ai05s/ai05-0151-1.txt	2009/05/19 22:41:16	1.2
+++ ai05s/ai05-0151-1.txt	2009/06/08 03:18:32	1.3
@@ -1,31 +1,458 @@
-!standard  3.10.1(2/2)                                 09-05-19    AI05-0151-1/02
+!standard  3.10.1(2/2)                                 09-06-06    AI05-0151-1/03
 !class Amendment 09-04-29
-!status deleted 09-05-19
 !status work item 09-04-29
 !status received 09-04-29
 !priority High
 !difficulty Hard
-!subject Limited with and access types
+!subject Allow incomplete types as parameter and result types
+
 !summary
 
-This AI has been merged into AI05-0149-1.
+Make limited views of packages more useful by allowing more use
+of the incomplete types they make visible.
 
 !problem
 
+The limited with clause makes incomplete views of types visible.
+Tagged incomplete types are useful for formal parameters, but
+most other incomplete types are pretty much useless, except
+as the designated type of an access type.  It would be nice
+if a type declared in a package named in a limited with
+clause could be used somehow, if only as a parameter type.
+
 !proposal
 
+Incomplete types may be used as formal parameter and result types,
+so long as they are fully defined at the point of call and at
+the point where the body is defined.
+
+Incomplete types may *not* be used for components or objects.
+
+For tagged incomplete types, we will continue to permit them as
+parameters even in calls and in a body, provided the incomplete type
+comes from a limited view of a package, rather than from an incomplete
+type declaration.  For non-tagged incomplete types, they will not be
+permitted in calls or in a body.  If the parameter or result type was
+incomplete at the point of declaration, any call or the body must be
+within the scope of a *non* limited view of the package defining the
+type.
+
 !wording
 
+** TBD **
+
 !discussion
 
+This proposal originally focused on a concern that a "limited with"
+naming a package with named access types forces the use of a lot of
+explicit conversion and/or anonymous access types in the clients.  We
+originally proposed to allow "incomplete access types" to be used as
+formal parameters and result types, to avoid the need for all of the
+conversion.  However, after analysis of the issues involved, it became
+clear that it was possible to generalize, and in some ways simplify, the
+proposal by allowing the use of *any* incomplete type as a parameter or
+result type, provided that the full definition was available at the
+point of call or at the definition of the body of the subprogram.
+
+An incomplete type is OK as a parameter or result since, until there is a
+call, there is no need to know the representation of the type.  This is
+in contrast to the case with components, where an aspect clause would
+need to be obeyed to ensure that streaming, aliased objects, etc., work
+as expected.
+
+Currently compilers generally do know the representation of the
+parameters and result at the point of declaration of a subprogram
+(though not for access-to-subprogram declarations). However, it should
+be possible to handle the lack of such representation information by
+having the compiler implicitly create a local access-to-subprogram type
+at the point of call, and then call through that, using only the address
+of the subprogram with incomplete types in its declaration, while determining
+the parameter passing mechanism from the access-to-subprogram type.
+
+Note that we have chosen to allow incomplete types as function results,
+even though we restricted tagged incomplete types to being parameters
+only.  This seems inconsistent.  Why should tagged incomplete types be
+*more* restrictive than incomplete types in general? Well, they
+shouldn't be, so with this proposal, the only advantage a tagged
+incomplete type will have is that a call or body *will* be permitted on
+a subprogram with tagged incomplete parameters, provided they are not
+controlling parameters.  Tagged or untagged incomplete types will be
+permitted as both parameters and results when declaring a subprogram.
+
+The net effect of this proposal is that changing a "with" to a "limited with"
+will be much less of a disruption for a client package, since it may continue
+to declare subprograms using the types from the limited-with'ed package.
+It won't be able to use those types as component types, but access types
+are frequently an adequate work-around in that case.
+
+Generic Formal Incomplete Types?
+
+I wonder whether we could have generic formal incomplete
+types as a way to allow instantiation with a private type before
+it is completely defined.  This might be sufficient for a "signature"
+generic.
+
 !example
 
+--!corrigendum 3.10.1(2/2)
+
+
 !ACATS test
 
+Add ACATS tests for this new feature.
 
 !appendix
 
+From: Tucker Taft
+Sent: Saturday, June 6, 2009  3:58 PM
+
+Here is an AI that came out of discussions about access types we have been
+having over the past couple of months.  Basically it allows incomplete types as
+parameter and result types, so long as at the point of call or the body the
+types are fully defined.
+
+This makes changing a "with" clause to a "limited with"
+clause *much* less disruptive, since there is no need to change the
+parameter/result profile of any subprograms declared in the client package just
+because the types might be incomplete because they are coming from a limited
+view of a package.
+
+[This is version /03 of the AI, the earlier versions were merged into AI05-149 and eliminated here. - ED]
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, June 6, 2009  4:30 PM
+
+> Here is an AI that came out of discussions about access types we have
+> been having over the past couple of months.  Basically it allows
+> incomplete types as parameter and result types, so long as at the
+> point of call or the body the types are fully defined.
+
+Seems like a big improvement to the language.  Ideally, access type should be
+used only when you really want reference semantics.  This change moves closer to
+that ideal.
+
+> This proposal originally focused on a concern that a "limited with"
+> naming a package with named access types forces the use of a lot of
+> explicit conversion and/or anonymous access types in the clients.  We
+> originally proposed to allow "incomplete access types" to be used as
+> formal parameters and result types, to avoid the need for all of the
+> conversion.  However, after analysis of the issues involved, it became
+> clear that it was possible to generalize, and in some ways simplify,
+> the proposal by allowing the use of *any* limited type as a parameter
+> or
+                                        ^^^^^^^ I think you mean "incomplete
+                                       type from a limited-with'ed package".
+
+[Corrected in the posted version /03, Editor.]
+
+> result type, provided that the full definition was available at the
+> point of call or at the definition of the body of the subprogram.
+>
+> An incomplete type is OK as a parameter or result since, until there
+> is a call, there is no need to know the representation of the type.
+> This is in contrast to the case with components, where an aspect
+> clause would need to be obeyed to ensure that streaming, aliased
+> objects, etc., work as expected.
+>
+> Currently compilers generally do know the representation of the
+> parameters and result at the point of declaration of a subprogram
+> (though not for access-to-subprogram declarations).
+
+What's the acc-to-subp case you're referring to?
+
+>... However, it should
+> be possible to handle the lack of such representation information by
+>having the compiler implicitly create a local access-to-subprogram type
+>at the point of call, and then call through that, using only the
+>address  of the subprogram with incomplete types in its declaration,
+>while determining  the parameter passing mechanism from the access-to-subprogram type.
+>
+> Note that we have chosen to allow incomplete types as function
+> results, even though we restricted tagged incomplete types to being
+> parameters only.  This seems inconsistent.  Why should tagged
+> incomplete types be
+> *more* restrictive than incomplete types in general? Well, they
+> shouldn't be, so with this proposal, the only advantage a tagged
+> incomplete type will have is that a call or body *will* be permitted
+> on a subprogram with tagged incomplete parameters, provided they are
+> not controlling parameters.  Tagged or untagged incomplete types will
+> be permitted as both parameters and results when declaring a subprogram.
+>
+> The net effect of this proposal is that changing a "with" to a "limited with"
+> will be much less of a disruption for a client package, since it may
+> continue to declare subprograms using the types from the limited-with'ed package.
+> It won't be able to use those types as component types, but access
+> types are frequently an adequate work-around in that case.
+
+That seems like a secondary benefit.  The primary benefit is that when you use
+"limited with" (in the first place) you don't have to use pointers when you
+don't want pointer semantics.  I'd say that first, then ``In addition, changing
+a "with" to a "limited with"...''.
+
+> Generic Formal Incomplete Types?
+>
+> I wonder whether we could have generic formal incomplete types as a
+> way to allow instantiation with a private type before it is completely
+> defined.  This might be sufficient for a "signature"
+> generic.
+
+Interesting idea.
+
+Does the "use package Blah" thing provide a different way to do signature
+generics?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, June 7, 2009  6:15 AM
+
+> ...  However, after analysis of the issues involved, it became
+>> clear that it was possible to generalize, and in some ways simplify,
+>> the proposal by allowing the use of *any* limited type as a parameter
+>> or
+>                                         ^^^^^^^ I think you mean
+> "incomplete type from a limited-with'ed package".
+
+Right you are.
+
+ > ...
+>> Currently compilers generally do know the representation of the
+>> parameters and result at the point of declaration of a subprogram
+>> (though not for access-to-subprogram declarations).
+>
+> What's the acc-to-subp case you're referring to?
+
+You are allowed to use incomplete types as parameter or result types in an
+access-to-subprogram type declaration.
+
+> ...
+>> Generic Formal Incomplete Types?
+>>
+>> I wonder whether we could have generic formal incomplete types as a
+>> way to allow instantiation with a private type before it is
+>> completely defined.  This might be sufficient for a "signature"
+>> generic.
+>
+> Interesting idea.
+>
+> Does the "use package Blah" thing provide a different way to do
+> signature generics?
+
+Yes, by putting most of the content of a (generic) package into an "integrated"
+subpackage, you can then follow the integrated subpackage with one or more
+generic instantiations, which are allowed to use private types defined in the
+integrated subpackage.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, June 6, 2009  3:24 PM
+
+I'm trying to figure out what is currently allowed for subprograms with
+parameters of a tagged incomplete type.  Calling a subprogram freezes its
+profile, and freezing its profile freezes all of its parameter types.  What
+happens when you freeze a tagged incomplete type?  Isn't that illegal if the
+type isn't completely defined?
+
+Are incomplete types produced by a limited view of a package "completely
+defined" everywhere, so that freezing them is OK?  I presume that freezing an
+incomplete type that is defined by an incomplete type declaration is illegal if
+it happens in a place outside the scope of the full definition.
+
+I am going to proceed in my work on AI05-0151 presuming that it is OK to freeze
+an incomplete type coming from the limited view of a package, and it has no
+effect, while freezing an incomplete type defined by an incomplete type
+declaration would be illegal outside the scope of the full type definition.
+
+I suspect this question needs a more explicit answer somewhere in the RM, or at
+least in the AARM.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, June 6, 2009  4:33 PM
+
+...
+> I suspect this question needs a more explicit answer somewhere in the
+> RM, or at least in the AARM.
+
+I'm puzzled by this message.  The version of AI05-0151-1v3 you just sent says
+you can't call a subp or give its body, until you have completion. Isn't that
+obviously necessary?
 
+Maybe if you gave an example of what you're asking, as in "Should the following
+be legal?"...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Saturday, June 6, 2009  9:56 PM
+
+> I'm trying to figure out what is currently allowed for subprograms
+> with parameters of a tagged incomplete type.
+> Calling a subprogram freezes its profile, and freezing its profile
+> freezes all of its parameter types.  What happens when you freeze a
+> tagged incomplete type?  Isn't that illegal if the type isn't
+> completely defined?
+
+13.14(17): "A type shall be fully defined before it is frozen." So, yes, of
+course, that is illegal.
+
+> Are incomplete types produced by a limited view of a package
+> "completely defined" everywhere, so that freezing them is OK?
+>  I presume that freezing an incomplete type that is defined by an
+> incomplete type declaration is illegal if it happens in a place
+> outside the scope of the full definition.
+
+I don't think this matters; either the completion exists (in which case it is
+fine to freeze it elsewhere) or it does not.
+
+I surely would expect that all entities imported by with clauses are considered
+frozen. That doesn't appear to be an explicit rules, but it is true because the
+exported entities are all frozen by the end of the spec. Since all views are
+frozen at once, that surely must include any exported incomplete views in the
+limited view of the package. QED. :-)
+
+And in this case, Robert's rule of absurdity would apply: if tagged limited
+views imported by with clauses were *not* frozen, it would be impossible to use
+them in subprogram parameters. Which would make all of the effort to define that
+moot. That's an absurd result.
+
+The AARM notes added by AI05-0017-1 (13.14(3.b-3.b.1/3)) sort of address this
+topic. but don't explicitly mention limited views. Probably we ought to add an
+AARM note to mention this meta-rule (probably in the Language Design
+Principles).
+
+Unrelated aside: 13.14(1.j) is misleading, as all of these entities have
+freezing and get frozen at particular points (for Convention and address clauses
+at least); I think the point of the note is that we don't use freezing per-se to
+handle most issues of premature access. Probably ought to be rewritten.
+
+> I am going to proceed in my work on AI05-0151 presuming that it is OK
+> to freeze an incomplete type coming from the limited view of a
+> package, and it has no effect, while freezing an incomplete type
+> defined by an incomplete type declaration would be illegal outside the
+> scope of the full type definition.
+
+That would be correct.
+
+> I suspect this question needs a more explicit answer somewhere in the
+> RM, or at least in the AARM.
+
+I think an AARM note is enough, since it clearly (!) follows from the existing
+freezing rules. But I would agree that it isn't obvious.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, June 7, 2009  6:21 AM
+
+...
+> I'm puzzled by this message.  The version of AI05-0151-1v3 you just
+> sent says you can't call a subp or give its body, until you have completion.
+> Isn't that obviously necessary?
+
+The issue is with the *current* rules that allow the use of tagged incomplete
+types as parameters. Can these be incomplete at the point of call or the body,
+provided they came from the limited view of a package?
+
+> Maybe if you gave an example of what you're asking, as in "Should the
+> following be legal?"...
+
+OK:
+
+     package P is
+        type T is tagged null record;
+     end P;
+
+     limited with P;
+     package Q is
+        procedure M(X : P.T);
+        type Acc is access T;
+     end Q;
+
+     -- NOTE: no "with" of P here
+     package body Q is
+        procedure M(X : P.T) is ... -- legal?
+
+        Y : Acc;
+
+     begin
+        M(Y.all);  -- legal?
+     end Q;
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, June 7, 2009  8:12 AM
+
+OK, I see what you're getting at.
+
+Both of the above had better be illegal, right?
+Y has to be null, but we plugged a hole like that in Ada 83.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, June 7, 2009  8:29 AM
+
+> Both of the above had better be illegal, right?
+
+No, I think our intent was that both of the above would be *legal*, since we
+know that tagged types are passed by reference, and so there is no problem
+passing them around even if you don't know anything about them.
+
+> Y has to be null, but we plugged a hole like that in Ada 83.
+
+I should have thrown in some "..." since my presumption was that Y might have
+been initialized by calling some function that returned an Acc.  That function
+would presumably be in another package which *does* have a non-limited "with" of
+P, and can legally do an allocator to create a non-null Acc value.
+
 ****************************************************************
 
+From: Randy Brukardt
+Sent: Sunday, June 7, 2009  9:38 PM
+
+> > Both of the above had better be illegal, right?
+>
+> No, I think our intent was that both of the above would be *legal*,
+> since we know that tagged types are passed by reference, and so there
+> is no problem passing them around even if you don't know anything
+> about them.
+
+That is my understanding as well. That is why 3.10(10/2) talks about *prefixes*
+that are of incomplete views, as opposed to *names* that are of incomplete
+views. The call cannot be a dispatching call (since we don't know where the tag
+is), but a simple "pass-through" call is allowed.
+
+OTOH, we can't support that for untagged types (because we don't know how
+they're passed) or for function results (since they are creating a new object,
+even for tagged types). So it seems that Tucker cannot rely solely on the
+freezing rules to implement the completeness check here.
+
+(That appears to be the difference between tagged and untagged incomplete types
+in this scheme, along with the use of 'Class: that you can declare bodies and
+make calls with tagged incomplete parameters/objects, but not with untagged
+incomplete.)
+
+> > Y has to be null, but we plugged a hole like that in Ada 83.
+>
+> I should have thrown in some "..." since my presumption was that Y
+> might have been initialized by calling some function that returned an
+> Acc.  That function would presumably be in another package which
+> *does* have a non-limited "with" of P, and can legally do an allocator
+> to create a non-null Acc value.
+
+Right, that was the idea. If a package is just passing a tagged object from one
+package to another, there is no need to know any details about the type, and, as
+Bob mentioned in another message, we don't want to force using access types
+unless the reference semantics are actually needed.
+
+I'm not sure this really works very well in practice, but it surely was intended
+to be possible.
+
+****************************************************************
 

Questions? Ask the ACAA Technical Agent