Version 1.1 of ai05s/ai05-0213-1.txt
!standard 3.10.1(9.3/2) 10-04-28 AI05-0213-1/01
!standard 12.5(2)
!standard 12.5.1(1/2)
!standard 12.5.1(6)
!standard 12.5.1(11)
!standard 12.5.1(17/2)
!standard 13.14(5)
!class amendment 10-04-28
!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
** TBD **
!proposal
(See wording.)
!wording
Add a new bullet after 3.10.1(9.3/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.} 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(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, 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.
!discussion
** TBD **
!example
** TBD **
--!corrigendum A.4.4(3)
!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 ::=
<as before> | 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 ::=
> <as before> | 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 ::=
>> <as before> | 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 ::=
>>> <as before> | 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.
****************************************************************
Questions? Ask the ACAA Technical Agent