Version 1.1 of acs/ac-00271.txt

Unformatted version of acs/ac-00271.txt version 1.1
Other versions for file acs/ac-00271.txt

!standard 4.1.6(2/3)          15-06-17 AC95-00271/00
!class confirmation 15-06-17
!status received no action 15-06-17
!status received 15-04-30
!subject Does a formal_package_declaration freeze the name template package?
!summary
!appendix

From: Gary Barnes
Sent: Thursday, April 30, 2015  2:13 PM

!topic formal_package_declaration causes freezing
!reference Ada Reference Manual, ISO/IEC 8652:2012(E)
!from Gary Barnes 15-04-30
!keywords formal_package_declaration freezing
!discussion

The question is whether a formal_package_declaration causes freezing for the
package named by generic_package_name.

12.7(2/3)
     formal_package_declaration ::=
            with package defining_identifier is new generic_package_name
          formal_package_actual_part
                [aspect_specification];

The standard would seem to answer Yes.

  12.7(4) The generic_package_name shall denote a generic package (the
          template for the formal package); the formal package is an instance
          of the template.

  12.3(1) [ An instance of a generic unit is declared by a
          generic_instantiation.]

  12.7(10.c) Ramification: A generic formal package is a package, and is an
             instance.  Hence, it is possible to pass a generic formal package
             as an actual to another generic formal package.

  13.14(5) The occurrence of a generic_instantiation causes freezing; ...

  13.14(3/3) The end of a declarative_part, protected_body, or a declaration
             of a library package or generic library package, causes freezing
             of each entity and profile declared within it, except for
             incomplete types.

  13.14(10.2/3) At the place where a generic_instantiation causes freezing of
                a callable entity, the profile of that entity is frozen.

  13.14(14/3) At the place where a profile is frozen, each subtype of the
              profile is frozen.

  13.14(15) At the place where a subtype is frozen, its type is frozen.

All of this means that the following package specification is in error
because Incomplete_Type is incomplete, and cannot be frozen, at the site of
the Parameter_Generic instantiation.   Correct?

package Generic_Formal_Package is

    type Incomplete_Type is private;         -- Incomplete

    generic
	type Generic_Formal_Type is (<>);
    package Parameter_Generic is
	subtype Incomplete_Type_Reference is -- Reference to Incomplete;
                                                 Incomplete_Type;
--   one form of many possible.
    end Parameter_Generic;

    generic
	with package Parameter is            -- Freezing?
                             new Parameter_Generic (<>);
    package Usage_Generic is
    end Usage_Generic;

private
    type Incomplete_Type is new Boolean;
end Generic_Formal_Package

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

From: Randy Brukardt
Sent: Thursday, June 4, 2015 11:15 PM

I'm working on creating AIs/filing mail, and I'm confused by this question,
because the example terminology is so confused.

Gary Barnes wrote:
...

...
> All of this means that the following package specification is in error
> because Incomplete_Type is incomplete, and cannot be
> frozen, at the site of the Parameter_Generic instantiation.   Correct?

Well, "Incomplete_Type" is not an incomplete type (it's a private type or
partial view). You're mixing terminology, which makes it impossible to tell what
problem you actually want us to look at.

Let's look at your example with the correct Ada terminology involved:

package Generic_Formal_Package is

   type Private_Type is private;         -- Private

   generic
      type Generic_Formal_Type is (<>);
   package Parameter_Generic is
      subtype Partial_View_Reference is -- Reference to a partial view
          Private_Type;                 --   one form of many possible.
   end Parameter_Generic; -- (1)

   generic
	with package Parameter is            -- Freezing? (2)
                             new Parameter_Generic (<>);
   package Usage_Generic is
   end Usage_Generic;

private
   type Private_Type is new Boolean;
end Generic_Formal_Package

There is no freezing at (1), because 13.14(3/3) only applies to library packages
(and this package is nested).

It's not completely clear why you would think there is freezing at (2). For your
list of paragraphs, it appears that you are thinking that a formal package
represents a generic instantiation (which it does) so that 13.14(5/3) applies
(which it clearly does not). Why not? Look at the start of the paragraph again:
   The occurrence of a generic_instantiation causes freezing...
Note that this uses the syntax term "generic_instantiation" and not the English
term "generic instantiation". They're not necessarily the same thing! In this
case, there is no "generic_instantation" (syntactic) in your program anywhere.
You have a "formal_package_declaration", which certainly is not a
"generic_instantiation". 13.14(5/3) [and 13.14(10.2/4) as well] don't apply.
There's no freezing at (2). QED.

I had thought that you had an example involving a formal package parameter, but
that would require an instance. Since instances are freezing, a formal parameter
itself isn't an issue. But I wonder about nested generics directly. Let's try an
experiment:

package Randys_Generic_Formal_Package_Example is

   type Private_Type is private;         -- Private

   generic
      type Generic_Formal_Type is (<>);
   package Parameter_Generic is
      subtype Partial_View_Reference is
          Private_Type; -- (1)
      function Foo (A : Private_Type) return Boolean; -- (2)
      type Bar is range 1 .. 10 with Size => Bar_Size; -- (3)
   end Parameter_Generic;

   package P is new Parameter_Generic (Integer); -- (4)

   Bar_Size : constant := 8;

private
   type Private_Type is new Boolean;
end Randys_Generic_Formal_Package_Example;

13.14(5/3) says that the instance at (4) is freezing. That freezes Integer
(already frozen) and Parameter_Generic.

But here, the rules lead to nonsense. 13.14(4/1) says that the name
"Parameter_Generic" causes freezing, but I don't understand what happens after
that.

There is no rule that says what happens when a package (or subprogram) is
frozen. That means nothing (extra) happens. 13.14(3/3) does most of the dirty
work.

So we're left with 13.14(4/1).

If one assumes the "construct" as described in 13.14(4/1) is the "name", then it
appears that the contents of Parameter_Generic are never frozen until the end of
the library package, because there is no "construct" to trigger the contents
part of 13.14(4/1) for the generic package. (And while the entity
Parameter_Generic is frozen, as previously noted that doesn't seem to have any
effect on the contents. Keep in mind that "is frozen" and "causes freezing" are
different things.) But that's nonsense, because a compiler would have to
generate an instance of a generic unit containing unfrozen entities, potentially
including code to elaborate the entity. (In this example, Bar, item (3) is not
frozen, the size hasn't even been declared yet.)

If one assume the "construct" as described in 13.14(4/1) is the generic unit,
then some of the contents of Parameter_Generic are frozen at the point of the
instance. But only "name, expression, implicit_dereference, or range" are
involved. It's not clear if this means anywhere within or top-level only.

If it is top-level only, then we have the same problem as before. There aren't
any of the listed items in a generic package.

If it is anywhere in the construct, we still have trouble. Declarations have
defining_identifiers, not names, so Foo and Bar themselves would not be
involved. A subtype_mark is a name, so Private_Type would be frozen in (1) and
(2) [meaning that the program is illegal, since the full type has not yet been
seen, violating 13.14(17)]. But this too is nonsense, as we don't want to freeze
a profile until the first call (or the end of the library unit). We definitely
don't want (2) to be illegal (the package should be legal if (1) and (3) are not
present).

So every interpretation I can come up with is nonsense. That doesn't look too
good. :-)

So, to summarize:
 (1) Gary's example is nonsense -- and there is no problem with it.
 (2) The example I thought he was asking about seems to trigger nonsense,
     because there don't appear to be any rules that do anything sensible.

Hopefully, Steve will straighten me out. Else the ARG will have a fun time.

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

From: Tucker Taft
Sent: Friday, June 5, 2015  9:49 AM

> If one assumes the "construct" as described in 13.14(4/1) is the
> "name", then it appears that the contents of Parameter_Generic are
> never frozen until the end of the library package, because there is no
> "construct" to trigger the contents part of 13.14(4/1) for the generic
> package. (And while the entity Parameter_Generic is frozen, as
> previously noted that doesn't seem to have any effect on the contents.
> Keep in mind that "is frozen" and "causes freezing" are different
> things.) But that's nonsense, because a compiler would have to
> generate an instance of a generic unit containing unfrozen entities,
> potentially including code to elaborate the entity. (In this example,
> Bar, item (3) is not frozen, the size hasn't even been declared yet.)

Freezing a generic per-se has no effect (see AARM 13.14(1.j/3) for some
discussion of this).  I realize in the RR implementation generics are compiled
at the time they are encountered, but the manual presumes more of a
macro-expansion semantics, so the "macro" itself (the generic template) does not
need to be frozen, since it is just a template. When you instantiate it, then
you freeze (most of) the actual parameters.  But the types and objects created
by the instantiation are not frozen immediately.  Like other declarations, they
wait until a "general" freezing point, or until they are referenced directly.

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

From: Randy Brukardt
Sent: Friday, June 5, 2015  7:08 PM

> Freezing a generic per-se has no effect (see AARM
> 13.14(1.j/3) for some discussion of this).  I realize in the RR
> implementation generics are compiled at the time they are encountered,
> but the manual presumes more of a macro-expansion semantics, so the
> "macro"
> itself (the generic template) does not need to be frozen, since it is
> just a template.

Right, I knew this. And I know the RRS implementation is formally wrong
(although in practice, there hardly is any noticeable difference); I was trying
to figure out what the actual rules are. (Although I'm dubious about your claim
that 13.14(1.j/3) is relevant; it's talking about access to bodies, not the
contents of a generic specification.)

> When you instantiate it, then you freeze (most of) the actual
> parameters.  But the types and objects created by the instantiation
> are not frozen immediately.  Like other declarations, they wait until
> a "general" freezing point, or until they are referenced directly.

But this seems like nonsense. You have to generate code to elaborate (some) of
the contents of the package, but it doesn't make sense to be elaborating things
that aren't frozen. If we had an object of type Bar in the package, that had
better get frozen no later than the instance, and I couldn't find any rules that
would cause that. That because the rules are all in terms of source constructs,
but there are no source constructs of the original generic in the instance. For
all other implicit things (like default expressions for parameters), we have
explicit rules how they freeze. But not for the contents of a generic instance.
That seemed bizarre.

But you accidentally pointed out the cause of the problem. 12.3 actually says
that the *text* of the template is duplicated. That model is completely insane
and meaningless, which is why I forget it immediately after reading it. (The
model is brain-damaged because it is talking about source text, which always is
unresolved; but then it says that "interpretation of each construct is the same
as in the template" -- which is a nonsense statement - a syntax construct is
what it says it is, once it is "interpreted" (that is, resolved), it's no longer
source text at all, it's just a reference to some entity. (In a compiler, that
could in many forms - a tree, a list of records, a slice of a symbol table, but
the one form it could never be is "source text").

Anyway, even though the model is criminally brain-damaged, it does effectively
answer my question. (It doesn't answer how a compiler might be able to generate
code to elaborate the contexts of an instance; most likely that happens by
freezing what has to be frozen and completely ignoring what 13.14 has to say.)

So there doesn't seem to be any problem that the ARG has to deal with.
(Well, there's one, but it's associated with the AI12-0155-1 that you [Tucker]
and I are working on. I'll send that privately.) So this thread does not need an
AI.

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

From: Tucker Taft
Sent: Monday, June 8, 2015  9:14 AM

> ... Anyway, even though the model is criminally brain-damaged, it does
> effectively answer my question. (It doesn't answer how a compiler
> might be able to generate code to elaborate the contexts of an
> instance; most likely that happens by freezing what has to be frozen
> and completely ignoring what
> 13.14 has to say.)

I think the key is that the language presumes a multi-pass model.  You don't
generate code for declarations right away, but wait at least until the freezing
point for the declaration, so you have seen all of the representation items that
might affect it.  I believe this applies to a generic instantiation as well.
That is, you don't generate code for a generic instance until you have reached
the end of the enclosing library item declaration, or a "general" freezing point
(which is *not* triggered by a generic instantiation).

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

From: Randy Brukardt
Sent: Monday, June 8, 2015  3:28 PM

> > ... Anyway, even though the model is criminally brain-damaged, it
> > does effectively answer my question. (It doesn't answer how a
> > compiler might be able to generate code to elaborate the contexts of
> > an instance; most likely that happens by freezing what has to be
> > frozen and completely ignoring what 13.14 has to say.)
>
> I think the key is that the language presumes a multi-pass model.  You
> don't generate code for declarations right away, but wait at least
> until the freezing point for the declaration, so you have seen all of
> the representation items that might affect it.

Where do you get this idea? Ada 83 was definitely compilable in one-pass (it's
not trivial, but it is possible), and I know there was a lot of pressure on the
Ada 9x team to keep it that way. I know of nothing that would have changed the
requirements.

It's never been the case that *type* declarations get immediate code generation,
but that's OK because a type does not generate any code. But objects and
constraints can get immediately evaluated and code generated -- the freezing
rules make that possible (object declarations and any constraint that is dynamic
cause freezing). That means almost all declarations can be immediately code
generated.

> I believe this applies to a generic
> instantiation as well.  That is, you don't generate code for a generic
> instance until you have reached the end of the enclosing library item
> declaration, or a "general" freezing point (which is *not* triggered
> by a generic instantiation).

I don't see how that's possible, because of the elaboration issues involved.

And the latter statement is false for that vast majority of generics, since the
occurrence of a body is a "general freezing point", and the text model means
that the body of the generic occurs right there. The only time a generic
instantiation might not be such a "general freezing point" is if it has no body
at all, that's a pretty rare occurrence. (For Ada 95, I considered it
pathological,as there was nothing useful you could do with such a thing.
Nowdays, with expression functions and null procedures and interfaces and the
like, there are some uses.)

Anyway, I discussed this in detail in the private message I sent, and let's
discuss this privately rather than here, because we're getting far afield.

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

From: Tucker Taft
Sent: Monday, June 8, 2015  3:51 PM

> Where do you get this idea? Ada 83 was definitely compilable in
> one-pass (it's not trivial, but it is possible), and I know there was
> a lot of pressure on the Ada 9x team to keep it that way. I know of
> nothing that would have changed the requirements.

I don't agree.  Declarations require at least some delay until their freezing
point, which in the worst case is not until the end of the enclosing library
package declaraiton.

> It's never been the case that *type* declarations get immediate code
> generation, but that's OK because a type does not generate any code.

In general you have to generate code to elaborate dynamic parts of type
declarations.  I realize that RR might take a different approach and insert
levels of indirection in some cases.

> ... But
> objects and constraints can get immediately evaluated and code
> generated -- the freezing rules make that possible (object
> declarations and any constraint that is dynamic cause freezing). That
> means almost all declarations can be immediately code generated.

Again, I don't see that, since you can put a pragma Import after an object
declaration, effectively canceling default initialization.

>> I believe this applies to a generic
>> instantiation as well.  That is, you don't generate code for a
>> generic instance until you have reached the end of the enclosing
>> library item declaration, or a "general" freezing point (which is
>> *not* triggered by a generic instantiation).
>
> I don't see how that's possible, because of the elaboration issues involved.

Elaboration relates to the order of execution, not to how long the compiler
waits before it starts generating code for a declaration.

> And the latter statement is false for that vast majority of generics,
> since the occurrence of a body is a "general freezing point", and the
> text model means that the body of the generic occurs right there.

I think you are taking the "text model" too far here.  As far as I know, a
generic instantiation freezes (most of) the actual parameters, but not anything
else preceding it.

> ... The only time a
> generic instantiation might not be such a "general freezing point" is
> if it has no body at all, that's a pretty rare occurrence. (For Ada
> 95, I considered it pathological,as there was nothing useful you could
> do with such a thing. Nowdays, with expression functions and null
> procedures and interfaces and the like, there are some uses.)

Hmmm..., you sound pretty sure here, but I am pretty certain that the average
Ada compiler permits a private type declaration, followed by a generic
instantiation not involving that private type, and then the full type
declaration.  I might think that even RR supports that.

> Anyway, I discussed this in detail in the private message I sent, and
> let's discuss this privately rather than here, because we're getting far afield.

Not sure why this is that far afield, as it relates pretty closely to the
general freezing model.

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

From: Randy Brukardt
Sent: Monday, June 8, 2015  4:37 PM

...
> > It's never been the case that *type* declarations get immediate code
> > generation, but that's OK because a type does not generate any code.
>
> In general you have to generate code to elaborate dynamic parts of
> type declarations.  I realize that RR might take a different approach
> and insert levels of indirection in some cases.

In a sensible model :-), types don't have dynamic parts. Objects of a particular
type might have a dynamic part, but the type is just a descriptor. (I realize
the Ada model is somewhat different, but since it leads to madness, I ignore it
and just worry about the visible effects. At least when I'm talking about our
implementation.)

> > ... But
> > objects and constraints can get immediately evaluated and code
> > generated -- the freezing rules make that possible (object
> > declarations and any constraint that is dynamic cause freezing).
> > That means almost all declarations can be immediately code generated.
>
> Again, I don't see that, since you can put a pragma Import after an
> object declaration, effectively canceling default initialization.

Ah, there's more than one way to skin a cat. (Humm, that sounds like animal
abuse! It's just a phrase.) Since the Janus/Ada parser runs separately (back in
the the dark ages of CP/M, we only had enough room for the parse table and hash
table, so the semantics had to be done later), we collect hints about the
syntax. Of course, they're purely syntactic, but for things like pragma
Interface/Import, address clauses, and the names of labels, they are purely
syntactic (if Ada ever allowed overloading of objects, that would change, but
for now that's sufficient). So we know if that might happen beforehand, but it
has nothing to do with delaying declarations (unless one considers that *all* of
the declarations are delayed -- but that then is essentially the same as
delaying none of them).

...
> > And the latter statement is false for that vast majority of
> > generics, since the occurrence of a body is a "general freezing
> > point", and the text model means that the body of the generic occurs right there.
>
> I think you are taking the "text model" too far here.  As far as I
> know, a generic instantiation freezes (most of) the actual parameters,
> but not anything else preceding it.
>
> > ... The only time a
> > generic instantiation might not be such a "general freezing point"
> > is if it has no body at all, that's a pretty rare occurrence. (For
> > Ada 95, I considered it pathological, as there was nothing useful
> > you could do with such a thing. Nowdays, with expression functions
> > and null procedures and interfaces and the like, there are some
> > uses.)
>
> Hmmm..., you sound pretty sure here, but I am pretty certain that the
> average Ada compiler permits a private type declaration, followed by a
> generic instantiation not involving that private type, and then the
> full type declaration.  I might think that even RR supports that.

Only if there is an ACATS test. :-)

If true, then there is a severe problem with the wording of the Standard. I
don't see how the "text" model can be used to describe freezing of an instance,
but only until it suddenly becomes inconvenient, at which point it no longer
applies. :-) That's what I wanted to discuss privately with you.

> > Anyway, I discussed this in detail in the private message I sent,
> > and let's discuss this privately rather than here, because we're
> > getting far afield.
>
> Not sure why this is that far afield, as it relates pretty closely to
> the general freezing model.

It's far afield for *this* thread, because it doesn't have anything to do with
the freezing of generic actuals. Moreover, if I've misinterpreted something
incorrectly, there's no point in cluttering the public record with my stupidity.
And if not, you are much better than me at concisely describing a problem, so I
should be able to better describe the problem when it does go public.

In any case, I put a lot more detail into the private message, and I'm not going
to spend another 90 minutes writing a message and examples again. Please comment
on them and we can try to figure out what is wrong (if anything) with the
Standard.

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

Questions? Ask the ACAA Technical Agent