!standard 3.10.1(8/2) 11-05-14 AI05-0213-1/03 !standard 12.5(2) !standard 12.5.1(1/2) !standard 12.5.1(6) !standard 12.5.1(11) !standard 12.5.1(18) !standard 13.14(5) !class amendment 10-04-28 !status Amendment 2012 11-05-11 !status ARG Approved (by Letter Ballot) 10-0-1 11-05-16 !status work item 11-04-26 !status No Action (8-0-2) 10-06-19 !status work item 10-04-28 !status received 10-04-26 !priority Low !difficulty Medium !subject Formal incomplete types !summary Add formal incomplete types. !problem There are situations where it is desirable to instantiate a generic with a private type before it has been completely defined. Unfortunately a generic instantiation freezes all of its actual parameters. In cases where the formal type is not used in a way that requires a completely defined type, it would be valuable if there were a kind of formal type that did not freeze the actual upon instantiation. !proposal (See wording.) !wording Add a new bullet after 3.10.1(8/2): * As a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1). Replace 12.5(2) with: formal_type_declaration ::= formal_complete_type_declaration | formal_incomplete_type_declaration formal_complete_type_declaration ::= type defining_identifier[discriminant_part] is formal_type_definition; formal_incomplete_type_declaration ::= type defining_identifier[discriminant_part] [is tagged]; In 12.5(6/2) replace For a formal_private_type_definition the reserved words tagged and limited indicate the category of types (see 12.5.1). with For a formal_private_type_definition the reserved words tagged and limited indicate the category of types (see 12.5.1). The reserved word tagged also plays this role in the case of a formal_incomplete_type_declaration. Modify 12.5.1(1/2): In its most general form, the category determined for a formal private type is all types, but [it]{the category} can be restricted to only nonlimited types or to only tagged types. {Similarly, the category for a formal incomplete type is all types but the category can be restricted to only tagged types; unlike other formal types, the actual type does not need to be able to be frozen (see 13.14).} The category determined for a formal derived type is the derivation class rooted at the ancestor type. Replace 12.5.1(6): If a formal private or derived subtype is definite, then the actual subtype shall also be definite. A formal_incomplete_type_declaration declares a formal incomplete type. The only view of a formal incomplete type is an incomplete view. [Redundant: Thus, a formal incomplete type is subject to the same usage restrictions as any other incomplete type - see 3.10.1] Modify 12.5.1(11): For a generic formal private {or incomplete} type with a known_discriminant_part: Append after 12.5.1(18): The category determined for a formal incomplete type is the category of all types, unless the formal_type_declaration includes the reserved word *tagged*; in this case, it is the category of all tagged types. Replace 13.14(5): The occurrence of a generic_instantiation causes freezing, except that a name which is a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1) does not cause freezing. In addition, if a parameter of the instantiation is defaulted, the default_expression or default_name for that parameter causes freezing. AARM note: Thus, an actual parameter corresponding to a formal incomplete type parameter may denote an incomplete or private type which is not completely defined at the point of the generic_instantiation. !discussion A formal incomplete type which does not cause freezing of the actual upon instantiation nicely solves the challenge of allowing instantiations of certain kinds of simple generics in the same visible part where a private type is declared. The Iterator_Interfaces generic is such a generic (see AI05-0139-2); it is instantiated in the containers packages with a private type (see AI05-0212-1). Another important example of such a generic is a "signature" generic, such as the following: generic type Element; type Set; with function Union(Left, Right : Set) return Set is <>; with function Intersection(Left, Right : Set) return Set is <>; with function Unit_Set(Elem : Element) return Set is <>; with procedure Add(Elem : Element; To_Set : in out Set) is <>; ... package Set_Signature is end; Such a signature generic can be instantiated with a private "Set" type and then the instance can be passed into other generics that have a formal package such as: generic type VN is private; with package Sets is Set_Signature(Element => VN, others => <>); ... package Flow_Analysis is ... This allows the construction of a generic that needs a "Set" abstraction, such as a flow analysis package. This is not something that would be easy to do with just an Set "interface," since a "Set" abstraction needs to be parameterized by the element type. !example The set generic given above could be included in a set container package: generic type Element is private; package My_Sets is type Set is tagged private; function Union (Left, Right : Set) return Set; function Intersection (Left, Right : Set) return Set; function Unit_Set (Elem : Element) return Set; procedure Add (Elem : Element; To_Set : in out Set); ... package My_Set_Signature is new Set_Signature (Element, Set); private ... end My_Sets; This makes the signature immediately available for use (as in the Flow_Analysis package above). !corrigendum 3.10.1(8/2) @dinsa @xbullet in an @fa.> @dinst @xbullet !corrigendum 12.5(2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier[discriminant_part] >@b<@ft>@fa< formal_type_definition;>> @dby @xcode<@fa> @xcode<@fa@b<@ft>@fa< defining_identifier[discriminant_part] >@b<@ft>@fa< formal_type_definition [aspect_specification];>> @xcode<@fa@b<@ft>@fa< defining_identifier[discriminant_part] [>@b<@ft>@fa<];>> !corrigendum 12.5(6) @drepl The form of a @fa @i to which the formal type belongs. For a @fa the reserved words @b and @b indicate the category of types (see 12.5.1). For a @fa the category of types is the derivation class rooted at the ancestor type. For other formal types, the name of the syntactic category indicates the category of types; a @fa defines a discrete type, and so on. @dby The form of a @fa @i to which the formal type belongs. For a @fa the reserved words @b and @b indicate the category of types (see 12.5.1). The reserved word @b also plays this role in the case of a @fa. For a @fa the category of types is the derivation class rooted at the ancestor type. For other formal types, the name of the syntactic category indicates the category of types; a @fa defines a discrete type, and so on. !corrigendum 12.5.1(1) @drepl In its most general form, the category determined for a formal private type is all types, but it can be restricted to only nonlimited types or to only tagged types. The category determined for a formal derived type is the derivation class rooted at the ancestor type. @dby In its most general form, the category determined for a formal private type is all types, but the category can be restricted to only nonlimited types or to only tagged types. Similarly, the category for a formal incomplete type is all types but the category can be restricted to only tagged types; unlike other formal types, the actual type does not need to be able to be frozen (see 13.14). The category determined for a formal derived type is the derivation class rooted at the ancestor type. !corrigendum 12.5.1(6) @drepl If the formal subtype is definite, then the actual subtype shall also be definite. @dby If a formal private or derived subtype is definite, then the actual subtype shall also be definite. A @fa declares a formal incomplete type. The only view of a formal incomplete type is an incomplete view. Thus, a formal incomplete type is subject to the same usage restrictions as any other incomplete type @emdash see 3.10.1. !corrigendum 12.5.1(11) @drepl The declaration of a formal derived type shall not have a @fa. For a generic formal private type with a @fa: @dby The declaration of a formal derived type shall not have a @fa. For a generic formal private or incomplete type with a @fa: !corrigendum 12.5.1(18) @dinsa The presence of the reserved word @b determines whether the actual type may be abstract. @dinst The category determined for a formal incomplete type is the category of all types, unless the @fa includes the reserved word @b; in this case, it is the category of all tagged types. !corrigendum 13.14(5) @drepl @xbullet causes freezing; also, if a parameter of the instantiation is defaulted, the @fa or @fa for that parameter causes freezing.> @dby @xbullet causes freezing, except that a @fa which is a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1) does not cause freezing. In addition, if a parameter of the instantiation is defaulted, the @fa or @fa for that parameter causes freezing.> !ACATS test Create an ACATS B-Test(s) and C-Test(s) to check this feature, particularly the use with unfrozen types. !appendix From: Steve Baird Sent: Monday, April 26, 2010 12:36 PM Just so that we have something to discuss in time for the upcoming conference call, please find below the !wording section that Ed and I have come up with for the formal incomplete types AI. This is only the !wording section; the rest of the AI still needs to be written (I know, this is not the usual order in which things are done). I do have one remaining question that is vaguely related to this AI, but it probably belongs in a separate AI (if it even warrants that). Should we use this new mechanism to define predefined signature packages which would then be instantiated by the predefined container generics? E.g., a mapping_signature generic which would be instantiated by each of the predefined mapping generics, as in package Some_Map_Generic is type Map is private; ... package Signature is new Mapping_Signature (Map, ...); private end Some_Map_Generic; There is also a question about whether we want an example of this feature in the RM (as opposed to just in the AI, or in the AARM). -- Steve ======== !wording In 3.10.1, add another bulleted list item after the 9.3/2 item: As a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1). Modify 12.5(2: formal_type_declaration ::= type defining_identifier[discriminant_part] is formal_type_definition; becomes formal_type_declaration ::= type defining_identifier[discriminant_part] [is [formal_type_definition | tagged]]; In 12.5(6/2) replace For a formal_private_type_definition the reserved words tagged and limited indicate the category of types (see 12.5.1). with For a formal_private_type_definition or for a type for which no formal_type_definition is given (a formal incomplete type), the reserved words tagged and limited indicate the category of types (see 12.5.1). Insert after the first sentence of 12.5.1(1/2): Similarly, the category for a formal incomplete type is all types but it can be restricted to only tagged types. Replace 12.5.1(6) If the formal subtype is definite, then the actual subtype shall also be definite. with If a formal private or derived subtype is definite, then the actual subtype shall also be definite. If no formal_type_definition is given, then the formal_type_declaration declares a formal incomplete type. The only view of a formal incomplete type is an incomplete view. [Redundant: Thus, a formal incomplete type is subject to the same usage restrictions as any other incomplete type - see 3.10.1] In 12.5.1(11), replace For a generic formal private type with a known_discriminant_part: with For a generic formal private or incomplete type with a known_discriminant_part: Append after 12.5.1(17/2): The category determined for a formal incomplete type is the category of all types, unless the formal_type_declaration includes the reserved word *tagged*; in this case, it is the category of all tagged types. Replace 13.14(5): The occurrence of a generic_instantiation causes freezing; also, if a parameter of the instantiation is defaulted, the default_expression or default_name for that parameter causes freezing. with The occurrence of a generic_instantiation causes freezing, except that a name which is a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1) does not cause freezing. AARM note: Thus, such an actual parameter may denote a private type which is not completely defined at the point of the generic_instantiation. **************************************************************** From: Bob Duff Sent: Monday, April 26, 2010 12:53 PM > I do have one remaining question that is vaguely related to this AI, > but it probably belongs in a separate AI (if it even warrants that). > Should we use this new mechanism to define predefined signature > packages which would then be instantiated by the predefined container generics? Good idea. It's OK with me to keep it in the same AI, but I don't care too much. > There is also a question about whether we want an example of this > feature in the RM (as opposed to just in the AI, or in the AARM). Only if short. Otherwise, perhaps a "NOTE See A.999.9999 for an example." **************************************************************** From: Tucker Taft Sent: Monday, April 26, 2010 2:02 PM I would make container signatures a separate AI, but with references back and forth. I could see having a long discussion about what would be the ideal "signature" packages for the containers, and I don't think that would be helpful for deciding on the merits of this AI. I think an example would be helpful, if it can be kept relatively short. **************************************************************** From: Randy Brukardt Sent: Monday, April 26, 2010 8:49 PM I agree that the signatures should be a different AI. An example is required, but clearly that would be in the part of the AI that hasn't been written yet. **************************************************************** From: Steve Baird Sent: Monday, April 26, 2010 2:03 PM >> Should we use this new mechanism to define predefined signature >> packages which would then be instantiated by the predefined container >> generics? A wild-and-crazy alternative approach to this problem would be to allow certain very-restricted instantiations (e.g., must be a package, generic must be bodyless and have empty spec and private part, actual params cannot involve any expression evaluation, etc.) as child units of generics. Then users could define their own signature generics and then define instances thereof as child units of the predefined container generics, as in with My_Mapping_Signature; package Some_Predefined_Map_Generic.Signature is new My_Mapping_Signature (Map, ...); with Some_Predefined_Map_Generic.Signature; package Foo is package I1 is new Some_Map_Generic (Some_Type, ...); package I2 is new Signature_User (Formal_Pkg => I1.Signature); end Foo; Note that A(4) currently says The implementation may restrict children of language-defined library units (other than Standard). This might require a change in order to make the above example portable. A new form of "sprouting" is probably too big a change, but I thought I would mention the idea. **************************************************************** From: Tucker Taft Sent: Monday, April 26, 2010 2:04 PM > ... > > In 12.5(6/2) replace > For a formal_private_type_definition the reserved words tagged and > limited indicate the category of types (see 12.5.1). > with > For a formal_private_type_definition or for a type for which no > formal_type_definition is given (a formal incomplete type), the > reserved words tagged and limited indicate the category of types > (see 12.5.1). > ... Your suggestion for 12.5(6/2) seems a bit confusing, and it implies that "limited" can be applied to a formal incomplete type. I would consider breaking this into two sentences, one for formal privates, and one for formal incompletes. Otherwise, looks good. **************************************************************** From: Steve Baird Sent: Monday, April 26, 2010 2:36 PM I don't see the implication (I actually thought about this point), but I'll concede that it might seem a bit confusing. The wording I suggested originally could be viewed as being short for "... the reserved words tagged and limited, as they might be used in a syntactically correct formal_type_declaration, indicate the category ..." and it is left as an exercise for the reader to determine that a formal incomplete type cannot include the reserved word limited. The advantage of this approach is that it is both brief and, strictly speaking, correct. You have identified a disadvantage of this approach, but note that this is just introductory text for a construct that is described more precisely in 12.5.1. Does the following seem like enough of an improvement to justify the increase in word count: For a formal_private_type_definition the reserved words tagged and limited indicate the category of types (see 12.5.1). The reserved word tagged also plays this role in the case of a type for which no formal_type_definition is given (a formal incomplete type; see 12.5.1). ? **************************************************************** From: Tucker Taft Sent: Monday, April 26, 2010 2:57 PM I think this argues for having a separate production: formal_incomplete_type_declaration ::= type defining_identifier [discriminant_part] [is tagged]; This will simplify wording elsewhere I suspect. It also matches better with how normal incomplete type syntax is presented. **************************************************************** From: Steve Baird Sent: Monday, April 26, 2010 3:14 PM > I think this argues for having a separate > production: > > formal_incomplete_type_declaration ::= > type defining_identifier [discriminant_part] [is tagged]; > That does seem clearer. Here are accompanying updates: Replace formal_type_declaration ::= type defining_identifier[discriminant_part] is formal_type_definition; with formal_type_declaration ::= | formal_incomplete_type_declaration . In 12.5(6/2) replace For a formal_private_type_definition the reserved words tagged and limited indicate the category of types (see 12.5.1). with For a formal_private_type_definition the reserved words tagged and limited indicate the category of types (see 12.5.1). The reserved word tagged also plays this role in the case of a formal_incomplete_type_declaration. In my original wording proposal for 12.5.1(6), replace If no formal_type_definition is given, then the formal_type_declaration declares a formal incomplete type. with A formal_incomplete_type_declaration declares a formal incomplete type. Does this all sound right? **************************************************************** From: Tucker Taft Sent: Monday, April 26, 2010 3:30 PM > Replace > > formal_type_declaration ::= > type defining_identifier[discriminant_part] is > formal_type_definition; > > with > > formal_type_declaration ::= > | formal_incomplete_type_declaration This is sort of a half-and-half production. I would prefer to see formal_incomplete_type_declaration directly beneath "generic_formal_parameter_declaration" in 12.1(6), or introduce a new non-terminal such as "formal_full_type_declaration" and have: formal_type_declaration ::= formal_full_type_declaration | formal_incomplete_type_declaration though that is using "full" in a somewhat different context than usual. > . > > In 12.5(6/2) replace > For a formal_private_type_definition the reserved words tagged and > limited indicate the category of types (see 12.5.1). > with > For a formal_private_type_definition the reserved words tagged and > limited indicate the category of types (see 12.5.1). > The reserved word tagged also plays this role in the case of a > formal_incomplete_type_declaration. > > In my original wording proposal for 12.5.1(6), replace > If no formal_type_definition is given, then the > formal_type_declaration declares a formal incomplete type. > with > A formal_incomplete_type_declaration declares a formal incomplete > type. > > Does this all sound right? Yes, it seems clearer. **************************************************************** From: Randy Brukardt Sent: Monday, April 26, 2010 9:16 PM Nit-picks... ... > Insert after the first sentence of 12.5.1(1/2): > Similarly, the category for a formal incomplete type is all types > but it can be restricted to only tagged types. The phrasing of this is really strange. I suppose it follows from the old wording, but it looks a lot weirder than that. Maybe the problem is the "it": > Similarly, the category for a formal incomplete type is all types > but the category can be restricted to only tagged types. I suppose we'd want to make a similar change to the existing wording in this paragraph to be consistent. ... > Append after 12.5.1(17/2): > > The category determined for a formal incomplete type is the > category of all types, unless the formal_type_declaration > includes the reserved word *tagged*; in this case, it is the > category of all tagged types. See, this is a lot easier to read. > Replace 13.14(5): > The occurrence of a generic_instantiation causes freezing; also, if a > parameter of the instantiation is defaulted, the default_expression or > default_name for that parameter causes freezing. > with > The occurrence of a generic_instantiation causes freezing, except that > a name which is a generic actual parameter whose corresponding > generic formal parameter is a formal incomplete type (see 12.5.1) > does not cause freezing. > > AARM note: Thus, such an actual parameter may denote a private > type which is not completely defined at the point of > the generic_instantiation. Shouldn't this note say "incomplete or private type"? Surely the actual can be an incomplete type (it would be bizarre if it could not). Later, Tucker suggests (replying to Steve): >> Replace >> >> formal_type_declaration ::= >> type defining_identifier[discriminant_part] is >> formal_type_definition; >> >> with >> >> formal_type_declaration ::= >> | formal_incomplete_type_declaration > >This is sort of a half-and-half production. > >I would prefer to see formal_incomplete_type_declaration >directly beneath "generic_formal_parameter_declaration" in 12.1(6), That would be a mess, as rules that apply to all generic_formal_types (the ones in 12.5) would have to be repeated or modified. Probably also would have to split this out from 12.5.1, as all of that also would have to be rewritten. Not worth it. (Although there would be some value to have a separate set of rules for this. If we were going to go this way, I'd suspect that this guy should have it's own subclause and not even appear in 12.5 or 12.5.1.) > or introduce a new non-terminal such as "formal_full_type_declaration" and > have: > formal_type_declaration ::= > formal_full_type_declaration > | formal_incomplete_type_declaration >though that is using "full" in a somewhat different context than usual. "Full" is surely wrong; the idea of a formal private type being a "full" type and a non-formal private type *not* being a "full" type is just too confusing. (I realize the actual has to be a full type, but we're not describing the actual.) Most of the wording with the "right" meaning have already been used (specific, definite came to mind). The important property of these formals is that they specify the category of type. So perhaps: formal_type_category_declaration Although that's a bit goofy, too, since the formal_incomplete_type_declaration does that as well. Maybe this is the wrong place to abstract this. How about: Replace formal_type_declaration ::= type defining_identifier[discriminant_part] is formal_type_definition; with formal_type_declaration ::= type defining_identifier[discriminant_part] formal_type_description; formal_type_description ::= is formal_type_definition | formal_incomplete_type_definition formal_incomplete_type_definition := [is tagged] Humm, Tucker probably won't like this, either. I see why Steve originally tried avoiding naming this. The problem here is that pesky "is"; it would be fine to have "formal_incomplete_type_definition", but that would have an extra "is", which doesn't work obviously. I'd rather not have any additional productions for the existing definition. I guess I'm out of ideas for now. Steve will just need to write up an AI and we can think about it some more. **************************************************************** From: Steve Baird Sent: Monday, April 26, 2010 10:54 PM >> Insert after the first sentence of 12.5.1(1/2): >> Similarly, the category for a formal incomplete type is all types >> but it can be restricted to only tagged types. > > The phrasing of this is really strange. I suppose it follows from the > old wording, but it looks a lot weirder than that. Maybe the problem > is the > "it": > I agree. I was just being consistent with the existing wording. >> Similarly, the category for a formal incomplete type is all types >> but the category can be restricted to only tagged types. > > I suppose we'd want to make a similar change to the existing wording > in this paragraph to be consistent. > If we don't mind rewriting existing wording, then I agree with your suggestion. >> Replace 13.14(5): >> The occurrence of a generic_instantiation causes freezing; also, if a >> parameter of the instantiation is defaulted, the default_expression or >> default_name for that parameter causes freezing. >> with >> The occurrence of a generic_instantiation causes freezing, except that >> a name which is a generic actual parameter whose corresponding >> generic formal parameter is a formal incomplete type (see 12.5.1) >> does not cause freezing. >> >> AARM note: Thus, such an actual parameter may denote a private >> type which is not completely defined at the point of >> the generic_instantiation. > > Shouldn't this note say "incomplete or private type"? Surely the > actual can be an incomplete type (it would be bizarre if it could not). > You are right that the actual can be an incomplete type, but this isn't the rule that makes this possible. The rule that allows an incomplete actual is in the list of allowed occurrences of a name that denotes an incomplete view of a type. That's why this case is not mentioned in this note. > Later, Tucker suggests (replying to Steve): > >>> Replace >>> >>> formal_type_declaration ::= >>> type defining_identifier[discriminant_part] is >>> formal_type_definition; >>> >>> with >>> >>> formal_type_declaration ::= >>> | formal_incomplete_type_declaration >> This is sort of a half-and-half production. >> >> I would prefer to see formal_incomplete_type_declaration >> directly beneath "generic_formal_parameter_declaration" in 12.1(6), > > That would be a mess, as rules that apply to all generic_formal_types > (the ones in 12.5) would have to be repeated or modified. Probably > also would have to split this out from 12.5.1, as all of that also > would have to be rewritten. Not worth it. (Although there would be > some value to have a separate set of rules for this. If we were going > to go this way, I'd suspect that this guy should have it's own > subclause and not even appear in 12.5 or > 12.5.1.) > I agree with Randy here. >> or introduce a new non-terminal such as >> "formal_full_type_declaration" and > have: >> formal_type_declaration ::= >> formal_full_type_declaration >> | formal_incomplete_type_declaration >> >> though that is using "full" in a somewhat different context than usual. > This approach seems better to me. > "Full" is surely wrong; the idea of a formal private type being a "full" > type and a non-formal private type *not* being a "full" type is just > too confusing. (I realize the actual has to be a full type, but we're > not describing the actual.) Most of the wording with the "right" > meaning have already been used (specific, definite came to mind). > The name "full" seems wrong (as Randy points out), but how about "complete", as in formal_type_declaration ::= formal_complete_type_declaration | formal_incomplete_type_declaration ? > I guess I'm out of ideas for now. > Steve will just need to write up an AI and we can think about it some more. How about the above (i.e., Tuck's second idea with the word "complete" instead of "full")? **************************************************************** From: Tucker Taft Sent: Monday, April 26, 2010 11:08 PM > ... > The name "full" seems wrong (as Randy points out), but how about > "complete", as in > > formal_type_declaration ::= > formal_complete_type_declaration > | formal_incomplete_type_declaration > ? This works for me. **************************************************************** From: Randy Brukardt Sent: Monday, April 26, 2010 11:19 PM OK by me, too. **************************************************************** From: Randy Brukardt Sent: Wednesday, April 28, 2010 8:29 PM For the record, I've created an AI out of this wording (filing the mail, and leaving everything else empty). It'll be AI05-0213-1. [This is version /01 of this AI.] As usual with these things, I found a bug. Steve had: Replace 13.14(5): The occurrence of a generic_instantiation causes freezing; also, if a parameter of the instantiation is defaulted, the default_expression or default_name for that parameter causes freezing. with The occurrence of a generic_instantiation causes freezing, except that a name which is a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1) does not cause freezing. AARM note: Thus, such an actual parameter may denote a private type which is not completely defined at the point of the generic_instantiation. But this wording change completely loses the part about default_expressions and names. That can't be intentional (the default stuff is not marked as redundant, and I can't think of any reason to skip it. So I used instead: Replace 13.14(5): The occurrence of a generic_instantiation causes freezing; also, if a parameter of the instantiation is defaulted, the default_expression or default_name for that parameter causes freezing. with The occurrence of a generic_instantiation causes freezing, except that a name which is a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1) does not cause freezing. In addition, if a parameter of the instantiation is defaulted, the default_expression or default_name for that parameter causes freezing. AARM note: Thus, an actual parameter corresponding to an formal incomplete type parameter may denote an incomplete or private type which is not completely defined at the point of the generic_instantiation. That's less than ideal (going from positive to negative and then back to positive), but we can discuss this further. (As far as the note goes, everytime I read the original version, I thought that for some reason that it didn't apply to incomplete types and had to reset my thinking. So I pulled rank and changed it even though Steve didn't want to.) **************************************************************** From: Randy Brukardt Sent: Wednesday, April 28, 2010 9:24 PM To explain something no one asked about (and better than in my last note): Steve Baird writes: ... > >> AARM note: Thus, such an actual parameter may denote a private > >> type which is not completely defined at the point of > >> the generic_instantiation. > > > > Shouldn't this note say "incomplete or private type"? Surely the > > actual can be an incomplete type (it would be bizarre if it could > > not). > > You are right that the actual can be an incomplete type, but this > isn't the rule that makes this possible. The rule that allows an > incomplete actual is in the list of allowed occurrences of a name that > denotes an incomplete view of a type. That's why this case is not > mentioned in this note. That's not true. Incomplete types freeze just like other types (with a couple of explicit exceptions). It just doesn't usually matter because they're rarely legally used in a context where they can be frozen "interestingly". Recall that 13.14(17) applies to incomplete types just as well as private types. But this is such an "interesting" context. Without this rule, it wouldn't be possible to pass an incomplete type whose completion hasn't been seen as an actual here, even with the extra wording in 3.10.1. Thus, "incomplete" needs to be mentioned in this note. **************************************************************** From: Steve Baird Sent: Thursday, April 29, 2010 12:14 AM > But this wording change completely loses the part about > default_expressions and names. That can't be intentional (the default > stuff is not marked as redundant, and I can't think of any reason to skip it. You are right, that was not intentional. Good catch. **************************************************************** From: Steve Baird Sent: Thursday, April 29, 2010 12:17 AM > Thus, "incomplete" needs to be mentioned in this note. Fine by me. **************************************************************** From: Tucker Taft Sent: Monday, May 2, 2011 9:44 PM [Part of this message that pertains to this AI.] AI05-0213-1/01 Formal incomplete types [This is unchanged (but previously No Action); we need this to enable the solution for the next two AIs.] Approve __X____ Disapprove ______ Abstain _______ Comments: Needs a problem and a discussion. How about: Problem: There are situations where it is desirable to instantiate a generic with a private type before it has been completely defined. Unfortunately a generic instantiation freezes all of its actual parameters. In cases where the formal type is not used in a way that requires a completely defined type, it would be valuable if there were a kind of formal type that did not freeze the actual upon instantiation. Discussion: A formal incomplete type which does not cause freezing of the actual upon instantiation nicely solves the challenge of allowing instantiations of certain kinds of simple generics in the same visible part where a private type is declared. The Iterator_Interfaces generic is such a generic (see AI-139). Another important example of such a generic is a "signature" generic, such as the following: generic type Element; type Set; with function Union(Left, Right : Set) return Set is <>; with function Intersection(Left, Right : Set) return Set is <>; with function Unit_Set(Elem : Element) return Set is <>; with procedure Add(Elem : Element; To_Set : in out Set) is <>; ... package Set_Signature is end; Such a signature generic can be instantiated with a private "Set" type and then the instance can be passed into other generics that have a formal package such as: generic type VN is private; with package Sets is Set_Signature(Element => VN, others => <>); ... package Flow_Analysis is ... This allows the construction of a generic that needs a "Set" abstraction, such as a flow analysis package. This is not something that would be easy to do with just an Set "interface," since a "Set" abstraction needs to be parameterized by the element type. ****************************************************************