!standard 9.5(53/5) 20-12-14 AI12-0399-1/03 !class Amendment 20-10-15 !status Amendment 1-2012 20-10-21 !status ARG Approved 13-1-0 20-10-21 !status work item 20-10-15 !status received 20-09-03 !priority Low !difficulty Easy !Subject Aspect specification for Preelaborable_Initialization !summary All Preelaborable_Initialization pragmas in the language-defined units are replaced by aspects. We allow for the situation for aspect Nonblocking where the full view is defined by the language or inheritance to be True, while the partial view is False. !problem (1) AI12-0409-1 defines a Preelaborable_Initialization aspect, and makes the Preelaborable_Initialization pragma obsolescent. However, the language-defined units still use the pragma. We generally do not use obsolescent features in the language-defined units. --- (2) AI12-0409-1 allows aspects to support the situation where the full view is defined by the language or inheritance to be True, while the partial view is False. It makes sense to allow this for Nonblocking, as it should allow the case where the full view might be defined by the language to be Nonblocking, even if the partial view defaults to False. !proposal (1) All Preelaborable_Initialization pragmas in the language-defined units are replaced by aspects. Note that AI12-0409-1 already replaced a few this way. (2) AI12-0409-1 modifies the general rule about partial view and full view having the same value for all aspects, to allow an exception for certain boolean-valued aspects, where the partial view may be False while the full view is True. We apply this to Nonblocking (though it is subtype-specific), given that certain subtypes are by definition Nonblocking, and having a requirement to specify Nonblocking => True for the partial view of such a subtype is not upward compatible. !wording Modify 3.9(6/5) type Tag is private[;] [pragma]{with} Preelaborable_Initialization[(Tag)]; Modify 7.6(5/2): type Controlled is abstract tagged private[;] [pragma]{with} Preelaborable_Initialization[(Controlled)]; Modify 7.6(7/2): type Limited_Controlled is abstract tagged limited private[;] [pragma]{with} Preelaborable_Initialization[(Limited_Controlled)]; Modify 9.5(53/5) as defined by AI12-0396-1: It is illegal to directly specify aspect Nonblocking for the first subtype of the full view of a type that has a partial view. If the Nonblocking aspect of the full view is inherited, it shall have the same value as that of the partial view{, or have the value True}. Modify 11.4.1(2/5): ... type Exception_Id is private[;] [pragma]{with} Preelaborable_Initialization[(Exception_Id)]; ... Modify 11.4.1(3/2): type Exception_Occurrence is limited private[;] [pragma]{with} Preelaborable_Initialization[(Exception_Occurrence)]; ... Modify 13.11(6/2): type Root_Storage_Pool is abstract new Ada.Finalization.Limited_Controlled with private[;] [pragma]{with} Preelaborable_Initialization[(Root_Storage_Pool)]; In a corresponding fashion: Modify 13.11.4(4/5), (5/3) Modify 13.13.1(3/2) Modify A.4.2(4/2): type Character_Set is private[;] [pragma]{with} Preelaborable_Initialization[(Character_Set)]; Modify A.4.5(4/2): type Unbounded_String is private[;] [pragma]{with} Preelaborable_Initialization[(Unbounded_String)]; Modify A.4.7(4/2): type Wide_Character_Set is private[;] [pragma]{with} Preelaborable_Initialization[(Wide_Character_Set)]; In a corresponding fashion: Modify A.4.8(4/2), (20/2) Modify A.12.1(5/4) Modify A.18.2(8/5), (9/2), (79.2/5), (79.3/5) Modify A.18.3(6/5), (7/2), (50.2/5), (50.3/5) Modify A.18.5(3/5), (4/2), (37.3/5), (37.4/5) Modify A.18.6(4/5), (5/2), (51.4/5), (51.5/5) Modify A.18.8(3/5), (4/2), (58.2/5), (58.3/5) Modify A.18.9(4/5), (5/2), (74.2/5), (74.3/5) Modify A.18.10(8.5), (9/3), (70.2/5), (70.3/5) Modify A.18.18(6/5) Modify B.3.1(5/2) Modify C.7.1(2/5) Modify G.1.1(4/2) !discussion (See !proposal.) !ASIS [Not sure. It seems like some new capabilities might be needed, but I didn't check - Editor.] !ACATS test ACATS B- and C-Tests are needed to check that the new capabilities are supported. !appendix From: John Barnes Sent: Thursday, September 3, 2020 2:39 PM I have started to update my book (Programming in Ada 2012) for Ada 202x. As a first pass I am correcting all (known) errors and updating it to reflect the 2015/2016 revision which is the current standard. Many of those changes are in the book anyway. I am also trying to avoid changing the pagination so that I don't have to make many changes to the index. One purpose of this version will be so that the publishers can use it for future print runs in the interim. (And as a safeguard against my never getting around to doing the full update for any reason such as personal termination.) At the same time I thought I might as well convert as many pragmas to aspects as possible even if they were not done by the 15/16 revision. But I was very surprised to find that there is no aspect form for the pragma Preelaborable_Initialization. I understand that there were a number of awkward cases where it was not possible. But all the cases that I have looked at and in particular important packages such as Ada,Tags, Ada.Exceptions, Ada.Finalization, Ada.Task_Identification, System.Storage_Pools and so on could easily use an aspect. In those examples it is simply a case of replacing type Something is sortof private; pragma Preelaborable_Initialization(Something); by type Something is sortof private with Preelaborable_Initialization; where sortof could be limited or abstract tagged or abstract tagged limited etc (or indeed nothing). I am assuming that when the final version is produced, we will use aspects in a uniform way throughout. At the moment some packages still have pragma Preelaborate whereas some use an aspect including for example Nonblocking which was convenient when Nonblocking was introduced. I have been through the whole of the 2012 RM and in every case where Preelaborable_Initialization is used, I could see no reason why an aspect could not be used. I did it by hand so maybe I missed something. What is the problem? **************************************************************** From: Tucker Taft Sent: Thursday, September 3, 2020 3:22 PM There was a technical reason we never made this an aspect (see http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai05s/ai05-0229-1.txt?rev=1.28): ===pragma Preelaborable_Initialization (referred to as P_I below) [Editor's Note: This pragma does not work well as a type-related aspect, as it is view dependent. In particular, even if a partial view does not have the P_I property, the full view might have the P_I property. That is contrary to 13.1(11/2) for operational and representation aspects. (In the absence of a change to 13.1(11/2), we'd have a compatibility problem.) We could try to invent new rules specifically for the P_I aspect to handle this, but it is more work than this could possibly be worth (there is no requirement for this pragma to be an aspect). Thus we are retaining the pragma and not defining an aspect.] --- This seems like it could be fixed, and it is a bit of an anomaly. I believe the goal was that it was OK if the partial view did not have the aspect visibly True, since you might change the implementation at some point to not have preelaborable initialization. On the other hand, for other aspects we are forcing you to reveal the full view's aspect in the partial view. Nonblocking is such an aspect. So I see two fixes: 1) Force the partial view to match the full view, and say that it has Preelaborable_Initialization, even if at some later point you fear the implementation might no longer be able to meet that requirement; 2) Allow the partial view and the full view to have different values for certain Boolean-valued aspects, but probably limited to False for the partial view and True for the full view. We already have a rule analogous to this on inheritance of Boolean aspects, in RM 13.1.1(18.1/5): "If an aspect of a derived type (or its first subtype) is inherited from an ancestor (sub)type and has the boolean value True, the inherited value shall not be overridden to have the value False for the derived type (or its first subtype), unless otherwise specified in this International Standard. If an aspect of a nonfirst subtype is inherited from the subtype in the subtype_indication that defines it, and has the value True, the inherited value shall not be overridden to have the value False for the nonfirst subtype, unless otherwise specified in this International Standard." We do allow aspects to be completely unspecified on a partial view, while being specified on the full view (RM 13.1.1(35/3)). So this could be seen as a variant of that for Boolean aspects for which "False" is the default value if not specified. Anyway, we need to decide whether we want to make this into an aspect. If so, we can probably make it work. **************************************************************** From: John Barnes Sent: Monday, September 7, 2020 3:34 AM Thanks for that. Reading that old AI will keep me quiet for a bit. I am also reading the 2012 Rationale which mentions the problem. I am somewhat horrified that I obviously knew about this once since I wrote the Rat and indeed it refers to that AI. But it would be excellent to find a neat way to tidy up this somewhat ugly remnant of widespread pragmas. **************************************************************** From: Tucker Taft Sent: Monday, September 7, 2020 3:01 PM Agreed. All we need is yet another AI to fix the problem! ;-) **************************************************************** From: Randy Brukardt Sent: Wednesday, September 9, 2020 2:51 PM Well, we still have numbers for 9600 possible AIs, so I don't think we need to worry about having more AIs. We *do* need a volunteer to write it, though. **************************************************************** From: Tucker Taft Sent: Wednesday, September 9, 2020 3:09 PM You can feel free to put it on my homework list. Not much there at the moment! **************************************************************** From: Bob Duff Sent: Wednesday, September 9, 2020 3:55 PM OK, so Tucker's homework is to write 9600 AIs. **************************************************************** From: Tucker Taft Sent: Wednesday, September 9, 2020 4:07 PM It sometimes feels that way... **************************************************************** From: Randy Brukardt Sent: Wednesday, September 9, 2020 4:09 PM > OK, so Tucker's homework is to write 9600 AIs. LOL! He's well on his way... :-) **************************************************************** From: Randy Brukardt Sent: Thursday, October 15, 2020 [Summary of some private mail on this proposal.] >> I don't think you have the Nonblocking rule (9.3(53/5)) correct, as it is >> written it prevents specifying the aspect to True on the full definition >> of a usual private type. According to your logic, that should be OK. It >> seems weird to only allow that by inheritance or rule (elementary base >> types). Tucker: > I don't think we want you to be able to *directly* specify the same aspect > with different values on the partial view and the full view. We do want you > to be able to specify one thing on the partial view, and then have the full > view inherit something else. Randy: That's not the case I was thinking about. The rule you have prevents specifying the value for the full type even if the partial view leaves it unspecified. That means that you cannot confirm an inherited value (unless you want to put it on the partial view and advertize it to the world), and similarly you can't use Nonblocking only in the body for most types. We have a language design principle that one can always write a confirming aspect specification, and this rule seems to violate that. I realize that Nonblocking is never truly "unspecified", but it is isn't mentioned and is inherited from the surrounding unit, which also might not explicitly specify the value, the difference is more academic than real. Tucker: >> ... That is the point. We are hiding the fact that the full view is >> Nonblocking, so we can change our minds without disturbing the rest of >> the world. Furthermore, the full view is going to be Nonblocking whether >> we want it to be or not if the full type is a scalar base subtype. >> ... >> [The existing rule] forced you to reveal whether the full type was >> Nonblocking, which you might not want to do to allow for later changes >> to the full type. Randy: > ... it is insane that you can do this *implicitly*, but you are not allowed > to do this *explicitly*. What the heck is the difference??? > So, I think you have to go all the way if you are making this change. Note > that you could always have a null subtype that has explicit Nonblocking on > it, so preventing it directly on the full type just is requiring name > pollution for no gain whatsoever. > >That is, you are allowing the following: > >package P is > type Priv is private; >private > type Priv is record ... > subtype Sub_Priv is Priv with Nonblocking => True; >end P; > >but not allowing: > >package P is > type Priv is private; >private > type Priv is record ... with Nonblocking => True; >end P; Tucker: I can see your point here. My main concern was not having different aspect values explicitly specified for the partial view and full view of the "same" subtype, because I think that will add complexity to implementations without sufficient benefit. Randy: I guess I can see splitting the baby here. I don't really buy the "complexity to implementations" argument, although given that we've removed the ability to retrieve the value of Nonblocking, someone might come up with something clever to avoid some work. For me [in Janus/Ada], I will just have to duplicate subtypes as needed to get the right effect, and that will get zero benefit from an additional restriction. But as I said before, it's very hard to say anything very definitive about other implementations. So, we probably should reword 9.5(53/5) to something like (changes not shown): It is illegal to directly specify aspect Nonblocking for the first subtype of the full view of a type that has a partial view with aspect Nonblocking specified. It is illegal to directly specify aspect Nonblocking to be False for the first subtype of the full view of a type that has a partial view that is nonblocking. If the Nonblocking aspect of the full view is inherited, it shall have the same value as that of the partial view, or have the value True. Alternatively, we could add the second sentence of the above to 9.5(54/5), in the same form: Aspect Nonblocking shall be directly specified for the first subtype of the full view of a type that has a partial view only if it has the same value as the Nonblocking aspect of the partial view or if it is specified True. **************************************************************** Editor's note: During meeting #62H, we voted to move most of this AI to AI12-0409-1 (and change that AI to a binding interpretation). Parts that don't need to apply to Ada 2012 are left here. ****************************************************************