Version 1.4 of ai12s/ai12-0399-1.txt
!standard 9.5(53/5) 21-02-10 AI12-0399-1/04
!standard 3.9(6/5)
!standard 7.6(5/2)
!standard 7.6(7/2)
!standard 11.4.1(2/5)
!standard 11.4.1(3/2)
!standard 13.11(6/2)
!standard 13.11.4(4/5)
!standard 13.11.4(5/5)
!standard 13.13.1(3/2)
!standard A.4.2(4/2)
!standard A.4.2(20/2)
!standard A.4.5(4/2)
!standard A.4.7(4/2)
!standard A.4.7(20/2)
!standard A.4.8(4/2)
!standard A.4.8(20/2)
!standard A.12.1(5/4)
!standard A.18.2(8/5)
!standard A.18.2(9/2)
!standard A.18.2(79.2/5)
!standard A.18.2(79.3/5)
!standard A.18.3(6/5)
!standard A.18.3(7/2)
!standard A.18.3(50.2/5)
!standard A.18.3(50.3/5)
!standard A.18.5(3/5)
!standard A.18.5(4/2)
!standard A.18.5(37.3/5)
!standard A.18.5(37.4/5)
!standard A.18.6(4/5)
!standard A.18.6(5/2)
!standard A.18.6(51.4/5)
!standard A.18.6(51.5/5)
!standard A.18.8(3/5)
!standard A.18.8(4/2)
!standard A.18.8(58.2/5)
!standard A.18.8(58.3/5)
!standard A.18.9(4/5)
!standard A.18.9(5/2)
!standard A.18.9(74.2/5)
!standard A.18.9(74.3/5)
!standard A.18.10(8/5)
!standard A.18.10(9/3)
!standard A.18.10(70.2/5)
!standard A.18.10(70.3/5)
!standard A.18.18(6/5)
!standard B.3.1(5/2)
!standard C.7.1(2/5)
!standard G.1.1(4/2)
!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.2(20/2):
-- Representation for a character to character mapping:
type Character_Mapping is private[;]
[pragma]{with} Preelaborable_Initialization[(Character_Mapping)];
Modify A.4.5(4/2):
type Unbounded_String is private[;]
[pragma]{with} Preelaborable_Initialization[(Unbounded_String)];
In a corresponding fashion:
Modify A.4.7(4/2), (20/2)
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.)
!corrigendum 3.9(6/2)
Replace the paragraph:
package Ada.Tags is
pragma Preelaborate(Tags);
type Tag is private;
pragma Preelaborable_Initialization(Tag);
by:
package Ada.Tags
with Preelaborate, Nonblocking, Global => in out synchronized is
type Tag is private
with Preelaborable_Initialization;
!corrigendum 7.06(5/2)
Replace the paragraph:
type Controlled is abstract tagged private;
pragma Preelaborable_Initialization(Controlled);
by:
type Controlled is abstract tagged private
with Preelaborable_Initialization;
!corrigendum 7.06(7/2)
Replace the paragraph:
type Limited_Controlled is abstract tagged limited private;
pragma Preelaborable_Initialization(Limited_Controlled);
by:
type Limited_Controlled is abstract tagged limited private
with Preelaborable_Initialization;
!corrigendum 9.5(17/3)
Insert after the paragraph:
In addition to the places where Legality Rules normally apply (see 12.3),
these rules also apply in the private part of an instance of a generic unit.
the new paragraphs:
Static Semantics
{{The remainder of this change is found in the conflict file.}}
!corrigendum 11.4.1(2/2)
Replace the paragraph:
with Ada.Streams;
package Ada.Exceptions is
pragma Preelaborate(Exceptions);
type Exception_Id is private;
pragma Preelaborable_Initialization(Exception_Id);
Null_Id : constant Exception_Id;
function Exception_Name(Id : Exception_Id) return String;
function Wide_Exception_Name(Id : Exception_Id) return Wide_String;
function Wide_Wide_Exception_Name(Id : Exception_Id)
return Wide_Wide_String;
by:
with Ada.Streams;
package Ada.Exceptions
with Preelaborate, Nonblocking, Global => in out synchronized is
type Exception_Id is private
with Preelaborable_Initialization;
Null_Id : constant Exception_Id;
function Exception_Name(Id : Exception_Id) return String;
function Wide_Exception_Name(Id : Exception_Id) return Wide_String;
function Wide_Wide_Exception_Name(Id : Exception_Id)
return Wide_Wide_String;
!corrigendum 11.4.1(3/2)
Replace the paragraph:
type Exception_Occurrence is limited private;
pragma Preelaborable_Initialization(Exception_Occurrence);
type Exception_Occurrence_Access is access all Exception_Occurrence;
Null_Occurrence : constant Exception_Occurrence;
by:
type Exception_Occurrence is limited private
with Preelaborable_Initialization;
type Exception_Occurrence_Access is access all Exception_Occurrence;
Null_Occurrence : constant Exception_Occurrence;
!corrigendum 13.11(6/2)
Replace the paragraph:
type Root_Storage_Pool is
abstract new Ada.Finalization.Limited_Controlled with private;
pragma Preelaborable_Initialization(Root_Storage_Pool);
by:
type Root_Storage_Pool is
abstract new Ada.Finalization.Limited_Controlled with private
with Preelaborable_Initialization;
!corrigendum 13.11.4(4/3)
Replace the paragraph:
type Root_Storage_Pool_With_Subpools is
abstract new Root_Storage_Pool with private;
by:
type Root_Storage_Pool_With_Subpools is
abstract new Root_Storage_Pool with private
with Preelaborable_Initialization;
!corrigendum 13.11.4(5/3)
Replace the paragraph:
type Root_Subpool is abstract tagged limited private;
by:
type Root_Subpool is abstract tagged limited private
with Preelaborable_Initialization;
!corrigendum 13.13.1(3/2)
Replace the paragraph:
type Root_Stream_Type is abstract tagged limited private;
pragma Preelaborable_Initialization(Root_Stream_Type);
by:
type Root_Stream_Type is abstract tagged limited private
with Preelaborable_Initialization;
!corrigendum A.4.2(4/2)
Replace the paragraph:
-- Representation for a set of character values:
type Character_Set is private;
pragma Preelaborable_Initialization(Character_Set);
by:
-- Representation for a set of character values:
type Character_Set is private
with Preelaborable_Initialization;
!corrigendum A.4.2(20/2)
Replace the paragraph:
-- Representation for a character to character mapping:
type Character_Mapping is private;
pragma Preelaborable_Initialization(Character_Mapping);
by:
-- Representation for a character to character mapping:
type Character_Mapping is private
with Preelaborable_Initialization;
!corrigendum A.4.5(4/2)
Replace the paragraph:
type Unbounded_String is private;
pragma Preelaborable_Initialization(Unbounded_String);
by:
type Unbounded_String is private
with Preelaborable_Initialization;
!corrigendum A.4.7(4/2)
Replace the paragraph:
-- Representation for a set of Wide_Character values:
type Wide_Character_Set is private;
pragma Preelaborable_Initialization(Wide_Character_Set);
by:
-- Representation for a set of Wide_Character values:
type Wide_Character_Set is private
with Preelaborable_Initialization;
!corrigendum A.4.7(20/2)
Replace the paragraph:
-- Representation for a Wide_Character to Wide_Character mapping:
type Wide_Character_Mapping is private;
pragma Preelaborable_Initialization(Wide_Character_Mapping);
by:
-- Representation for a Wide_Character to Wide_Character mapping:
type Wide_Character_Mapping is private
with Preelaborable_Initialization;
!corrigendum A.4.8(4/2)
Replace the paragraph:
-- Representation for a set of Wide_Wide_Character values:
type Wide_Wide_Character_Set is private;
pragma Preelaborable_Initialization(Wide_Wide_Character_Set);
by:
-- Representation for a set of Wide_Wide_Character values:
type Wide_Wide_Character_Set is private
with Preelaborable_Initialization;
!corrigendum A.4.8(20/2)
Replace the paragraph:
-- Representation for a Wide_Wide_Character to Wide_Wide_Character
-- mapping:
type Wide_Wide_Character_Mapping is private;
pragma Preelaborable_Initialization(Wide_Wide_Character_Mapping);
by:
-- Representation for a Wide_Wide_Character to Wide_Wide_Character
-- mapping:
type Wide_Wide_Character_Mapping is private
with Preelaborable_Initialization;
!corrigendum A.12.1(5/4)
Replace the paragraph:
type File_Type is limited private;
pragma Preelaborable_Initialization(File_Type);
by:
type File_Type is limited private
with Preelaborable_Initialization;
!corrigendum A.18.2(8/3)
Replace the paragraph:
type Vector is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
pragma Preelaborable_Initialization(Vector);
by:
type Vector is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type,
Iterator_View => Stable.Vector,
Aggregate => (Empty => Empty,
Add_Unnamed => Append,
New_Indexed => New_Vector,
Assign_Indexed => Replace_Element),
Stable_Properties => (Length, Capacity,
Tampering_With_Cursors_Prohibited,
Tampering_With_Elements_Prohibited),
Default_Initial_Condition =>
Length (Vector) = 0 and then
(not Tampering_With_Cursors_Prohibited (Vector)) and then
(not Tampering_With_Elements_Prohibited (Vector)),
Preelaborable_Initialization;
!corrigendum A.18.2(9/2)
Replace the paragraph:
type Cursor is private;
pragma Preelaborable_Initialization(Cursor);
by:
type Cursor is private
with Preelaborable_Initialization;
!corrigendum A.18.3(6/3)
Replace the paragraph:
type List is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
pragma Preelaborable_Initialization(List);
by:
type List is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type,
Iterator_View => Stable.List,
Aggregate => (Empty => Empty,
Add_Unnamed => Append),
Stable_Properties => (Length,
Tampering_With_Cursors_Prohibited,
Tampering_With_Elements_Prohibited),
Default_Initial_Condition =>
Length (List) = 0 and then
(not Tampering_With_Cursors_Prohibited (List)) and then
(not Tampering_With_Elements_Prohibited (List)),
Preelaborable_Initialization;
!comment A.18.2(79/2) is not formatted in AI12-0111-1, and will not be handled here, either.
!corrigendum A.18.3(7/2)
Replace the paragraph:
type Cursor is private;
pragma Preelaborable_Initialization(Cursor);
by:
type Cursor is private
with Preelaborable_Initialization;
!comment A.18.3(51/2) is not formatted in AI12-0111-1, and will not be handled here, either.
!corrigendum A.18.5(3/2)
Replace the paragraph:
type Map is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
pragma Preelaborable_Initialization(Map);
by:
type Map is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type,
Iterator_View => Stable.Map,
Aggregate => (Empty => Empty,
Add_Named => Insert),
Stable_Properties => (Length,
Tampering_With_Cursors_Prohibited,
Tampering_With_Elements_Prohibited),
Default_Initial_Condition =>
Length (Map) = 0 and then
(not Tampering_With_Cursors_Prohibited (Map)) and then
(not Tampering_With_Elements_Prohibited (Map)),
Preelaborable_Initialization;
!corrigendum A.18.5(4/2)
Replace the paragraph:
type Cursor is private;
pragma Preelaborable_Initialization(Cursor);
by:
type Cursor is private
with Preelaborable_Initialization;
!comment A.18.5(37/2) is not formatted in AI12-0111-1, and will not be handled here, either.
!corrigendum A.18.6(4/3)
Replace the paragraph:
type Map is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
pragma Preelaborable_Initialization(Map);
by:
type Map is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type,
Iterator_View => Stable.Map,
Aggregate => (Empty => Empty,
Add_Named => Insert),
Stable_Properties => (Length,
Tampering_With_Cursors_Prohibited,
Tampering_With_Elements_Prohibited),
Default_Initial_Condition =>
Length (Map) = 0 and then
(not Tampering_With_Cursors_Prohibited (Map)) and then
(not Tampering_With_Elements_Prohibited (Map)),
Preelaborable_Initialization;
!corrigendum A.18.6(5/2)
Replace the paragraph:
type Cursor is private;
pragma Preelaborable_Initialization(Cursor);
by:
type Cursor is private
with Preelaborable_Initialization;
!comment A.18.6(51/2) is not formatted in AI12-0111-1, and will not be handled here, either.
!corrigendum A.18.8(3/3)
Replace the paragraph:
type Set is tagged private
with Constant_Indexing => Constant_Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
pragma Preelaborable_Initialization(Set);
by:
type Set is tagged private
with Constant_Indexing => Constant_Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type,
Iterator_View => Stable.Set,
Aggregate => (Empty => Empty,
Add_Unnamed => Include),
Stable_Properties => (Length,
Tampering_With_Cursors_Prohibited),
Default_Initial_Condition =>
Length (Set) = 0 and then
(not Tampering_With_Cursors_Prohibited (Set)),
Preelaborable_Initialization;
!corrigendum A.18.8(4/2)
Replace the paragraph:
type Cursor is private;
pragma Preelaborable_Initialization(Cursor);
by:
type Cursor is private
with Preelaborable_Initialization;
!comment A.18.8(58/2) is not formatted in AI12-0111-1, and will not be handled here, either.
!corrigendum A.18.9(4/3)
Replace the paragraph:
type Set is tagged private
with Constant_Indexing => Constant_Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
pragma Preelaborable_Initialization(Set);
by:
type Set is tagged private
with Constant_Indexing => Constant_Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type,
Iterator_View => Stable.Set,
Aggregate => (Empty => Empty,
Add_Unnamed => Include),
Stable_Properties => (Length,
Tampering_With_Cursors_Prohibited),
Default_Initial_Condition =>
Length (Set) = 0 and then
(not Tampering_With_Cursors_Prohibited (Set)),
Preelaborable_Initialization;
!corrigendum A.18.9(5/2)
Replace the paragraph:
type Cursor is private;
pragma Preelaborable_Initialization(Cursor);
by:
type Cursor is private
with Preelaborable_Initialization;
!comment A.18.9(74/2) is not formatted in AI12-0111-1, and will not be handled here, either.
!corrigendum A.18.10(8/3)
Replace the paragraph:
type Tree is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
pragma Preelaborable_Initialization(Tree);
by:
type Tree is tagged private
with Constant_Indexing => Constant_Reference,
Variable_Indexing => Reference,
Default_Iterator => Iterate,
Iterator_Element => Element_Type,
Iterator_View => Stable.Tree,
Stable_Properties => (Node_Count,
Tampering_With_Cursors_Prohibited,
Tampering_With_Elements_Prohibited),
Default_Initial_Condition =>
Node_Count (Tree) = 1 and then
(not Tampering_With_Cursors_Prohibited (Tree)) and then
(not Tampering_With_Elements_Prohibited (Tree)),
Preelaborable_Initialization;
!corrigendum A.18.10(9/3)
Replace the paragraph:
type Cursor is private;
pragma Preelaborable_Initialization(Cursor);
by:
type Cursor is private
with Preelaborable_Initialization;
!comment A.18.10(70/3) is not formatted in AI12-0111-1, and will not be handled here, either.
!corrigendum A.18.18(6/3)
Replace the paragraph:
type Holder is tagged private;
pragma Preelaborable_Initialization (Holder);
by:
type Holder is tagged private
with Stable_Properties => (Is_Empty,
Tampering_With_The_Element_Prohibited),
Default_Initial_Condition => Is_Empty (Holder),
Preelaborable_Initialization;
!corrigendum B.3.1(5/2)
Replace the paragraph:
type chars_ptr is private;
pragma Preelaborable_Initialization(chars_ptr);
by:
type chars_ptr is private
with Preelaborable_Initialization;
!corrigendum C.7.1(2/2)
Replace the paragraph:
package Ada.Task_Identification is
pragma Preelaborate(Task_Identification);
type Task_Id is private;
pragma Preelaborable_Initialization (Task_Id);
Null_Task_Id : constant Task_Id;
function "=" (Left, Right : Task_Id) return Boolean;
by:
package Ada.Task_Identification
with Preelaborate, Nonblocking, Global => in out synchronized is
type Task_Id is private
with Preelaborable_Initialization;
Null_Task_Id : constant Task_Id;
function "=" (Left, Right : Task_Id) return Boolean;
!corrigendum G.1.1(4/2)
Replace the paragraph:
type Imaginary is private;
pragma Preelaborable_Initialization(Imaginary);
by:
type Imaginary is private
with Preelaborable_Initialization;
!ASIS
No ASIS effect.
!ACATS test
No ACATS tests needed.
!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.
****************************************************************
Questions? Ask the ACAA Technical Agent