Version 1.8 of ai05s/ai05-0213-1.txt

Unformatted version of ai05s/ai05-0213-1.txt version 1.8
Other versions for file ai05s/ai05-0213-1.txt

!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)
Insert after the paragraph:
the new paragraph:
!corrigendum 12.5(2)
Replace the paragraph:
formal_type_declaration ::= type defining_identifier[discriminant_part] is formal_type_definition;
by:
formal_type_declaration ::= formal_complete_type_declaration | formal_incomplete_type_declaration
formal_complete_type_declaration ::= type defining_identifier[discriminant_part] is formal_type_definition [aspect_specification];
formal_incomplete_type_declaration ::= type defining_identifier[discriminant_part] [is tagged];
!corrigendum 12.5(6)
Replace the paragraph:
The form of a formal_type_definition determines a category (of types) to which the formal type belongs. For a formal_private_type_definition the reserved words tagged and limited indicate the category of types (see 12.5.1). For a formal_derived_type_definition 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 formal_discrete_type_definition defines a discrete type, and so on.
by:
The form of a formal_type_definition determines a category (of types) to which the formal type belongs. 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. For a formal_derived_type_definition 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 formal_discrete_type_definition defines a discrete type, and so on.
!corrigendum 12.5.1(1)
Replace the paragraph:
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.
by:
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)
Replace the paragraph:
If the formal subtype is definite, then the actual subtype shall also be definite.
by:
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. Thus, a formal incomplete type is subject to the same usage restrictions as any other incomplete type — see 3.10.1.
!corrigendum 12.5.1(11)
Replace the paragraph:
The declaration of a formal derived type shall not have a known_discriminant_part. For a generic formal private type with a known_discriminant_part:
by:
The declaration of a formal derived type shall not have a known_discriminant_part. For a generic formal private or incomplete type with a known_discriminant_part:
!corrigendum 12.5.1(18)
Insert after the paragraph:
The presence of the reserved word abstract determines whether the actual type may be abstract.
the new paragraph:
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.
!corrigendum 13.14(5)
Replace the paragraph:
by:
!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.

****************************************************************

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.

****************************************************************


Questions? Ask the ACAA Technical Agent