!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. ***************************************************************