Version 1.4 of ai12s/ai12-0419-1.txt
!standard 3.2.4(1/5) 21-01-29 AI12-0419-1/03
!standard 3.2.4(29.5/4)
!standard 3.9.2(1/5)
!standard 4.2.1(6/5)
!standard 4.10(4/5)
!standard 4.10(7/5)
!standard 4.10(19/5)
!standard 7.3.2(3/4)
!standard 7.3.3(2/5)
!standard 12.5.1(21/3)
!standard 13.1(15.9/5)
!standard 13.1.1(18.3/5)
!standard 13.13.2(8.1/3)
!standard 13.13.2(9/3)
!standard 13.13.2(25/3)
!standard 13.13.2(25.1/2)
!standard 13.13.2(25.1/2)
!standard 13.13.2(42/2)
!class Amendment 21-01-14
!status Amendment 1-2012 21-01-21
!status ARG Approved 16-0-0 21-01-20
!status work item 21-01-14
!status received 21-01-14
!priority Low
!difficulty Medium
!subject Aspect inheritance and reemergence
!summary
Type-related and subtype-specific aspects that can mention subprograms
by name fall into different categories relating to whether and how they
are inherited, and whether for a formal untagged type, the operations of
the ancestor reemerge in an instance, or the aspects of the actual are
always used:
1) implicitly composed
Implicitly composed aspects are not inherited per se, but the
aspect for a derived type is implicitly composed from that of its
parent type. The aspects of an ancestor never "reemerge" in a
generic; the actual type's "actual" aspect definition is invoked.
This makes sense because these aspects are generally defined for
private types, and in that case there is no ancestor aspect to
reemerge.
2) additive
Additive aspects are not inherited, but they "apply" to their
descendants, using a "notional formal derived type" model. In
a generic, the type's "actual" aspect definition is invoked
as appropriate, even if untagged. As with the implicitly
composed aspects, these are meaningful on private types,
so reemergence of an ancestor's aspect would not make sense.
3) nonoverridable
Nonoverridable aspects are inherited, but cannot be overridden
except with a "confirming" definition which matches that of the
parent type as defined in 13.1. On the other hand, the named
subprograms can be overridden, and that is the way to alter the
effect of a nonoverridable aspect in a derived type. For a formal
untagged derived type, the ancestor's nonoverridable aspects, if
any, reemerge, which is not surprising because the primitive
subprograms of the untagged ancestor reemerge as well.
Ancestor aspects of formal tagged types never reemerge thanks to the
rule that the actual type's run-time tag controls which body is
executed.
For uniformity, we change the description of stream attributes of
untagged types to use the "implicitly composed" terminology rather than
inheritance, to better match what happens with tagged stream attributes.
This is not intended to change the semantics in any way; it is just a
presentation change that hopefully clarifies the semantics.
The Put_Image aspect is considered to be implicitly composed as well.
The user-defined literal aspects are nonoverridable.
!question
Is the Put_Image aspect inherited by a derived type? (Not exactly; it is
defined by default by a call on the parent's Put_Image, composed with,
if tagged, the Put_Image of any extension components.)
If not, what happens with untagged derived types? (They use an
implicitly defined Put_Image that calls the parent Put_Image.)
Does the Put_Image of the ancestor of a formal derived type reemerge in
a generic instance, or is the actual type's Put_Image used? (Actual
type.)
What are the general rules for inheritance and reemergence of
operational aspects? (This AI attempts to clarify them.)
What are the inheritance and re-emergence rules for the user-defined
literal aspects? (They are nonoverridable.)
!recommendation
See !summary.
!wording
[relative to AARM 202X Draft 27]
Modify 3.2.4(1/5):
The language-defined predicate aspects Static_Predicate and
Dynamic_Predicate may be used to define properties of subtypes. A
predicate specification is an aspect_specification for one of the two
predicate aspects. General rules for aspects and aspect_specifications
are found in Clause 13 (13.1 and 13.1.1 respectively). The predicate
aspects are assertion aspects (see 11.4.2).{ [Redundant: The
predicate aspects are not inherited, but their effects are additive,
as defined below.]}
Modify 3.2.4(29.5/4):
* if S is a first subtype, the value is tested to determine whether it
satisfies the predicates of the parent and progenitor subtypes (if
any) of S (in an arbitrary order){, after a (view) conversion of the
value to the corresponding parent or progenitor type};
Modify 3.9.2(1/5):
The primitive subprograms of a tagged type, the subprograms declared
by formal_abstract_subprogram_declarations, the [subprograms
identified by the user-defined literal aspects]{Put_Image attribute}
of a specific tagged type (see [4.2.1]{4.10}), and the stream
attributes of a specific tagged type that are available (see 13.13.2)
at the end of the declaration list where the type is declared are
called dispatching operations. [... rest as before]
Modify 4.2.1(6/5):
User-defined literal aspects are [inherited according to the rules
given in 13.1]{ nonoverridable (see 13.1.1)}.
Modify 4.10(4/5):
The Put_Image attribute may be specified for any specific type T
either via an attribute_definition_clause or via an
aspect_specification specifying the Put_Image aspect of the type.{
[Redundant: The Put_Image aspect is not inherited, but rather is
implicitly composed for derived types, as defined below.]}
Modify 4.10(5/5) (this makes three paragraphs out of one):
The behavior of the default implementation of S'Put_Image depends on the
class of T.{
For an untagged derived type, the default implementation of
T'Put_Image invokes the Put_Image for its parent type on
a conversion of the parameter of type T to the parent type.
}For {a nonderived}[an] elementary type, the implementation is equivalent to:
Make each paragraph 4.10(8/5-12/5) into a bullet.
Move a modified version of 4.10(17/5) and 4.10(18/5), as a single paragraph,
after 4.10(12/5):
For a type extension, the default implementation of T'Put_Image
depends on whether there exists a noninterface ancestor of T (other
than T itself) for which the Put_Image aspect has been [Redundant:
[explicitly]{directly}] specified. If so, then T'Put_Image will
generate an image based on extension aggregate syntax where the
ancestor type of the extension aggregate is the nearest ancestor type
whose Put_Image aspect has been specified. If no such ancestor exists,
then the default implementation of T'Put_Image is the same as described
below for {a nonderived}[an untagged] record type.
Discussion: This might generate an image such as "(This Text Was
User-Generated with C1 => 123, C2 => 456)" where the "This Text was
User-Generated" portion of the text was generated by the call to the
user-specified Put_Image routine {for the ancestor}.
Add after 4.10(12/5) [and the above moved paragraph]:
For a specific, nonderived composite type:
Move a modified and bulleted version of 4.10(15/5) after the above paragraphs:
{* If the default implementation of Put_Image writes components, the}[The]
order in which components are written [for a composite type ]is the same
canonical order in which components of a composite type T are written out
by the default implementation of T'Write. Redundant[This is also the order
that is used in determining the meaning of a positional aggregate of type T.]
Bullet 4.10(13/5).
Indent 4.10(14/5) [it is logically part of the preceding paragraph].
[4.10(15/5), 4.10(17/5), and 4.10(18/5) were moved above; 4.10(16/5) is moved below.]
Modify (and bullet) 4.10(19/5):
{*} For {a}[an untagged] untagged record type{ (or, as indicated
above, a type extension with no noninterface ancestor specifying Put_Image)},
a specific tagged record type other than a type extension which meets the
criteria described in the previous paragraph, or a protected type,
the default implementation of T'Put_Image generates an image based on named
(not positional) record aggregate
syntax (except that for a protected type, the initial left parenthesis is
followed by "PROTECTED with "). Component names are displayed in upper case,
following the rules for the image of an enumeration value. Component values
are displayed via calls to the component type's Put_Image procedure.
Indent 4.10(20/5) [it is logically part of the preceding paragraph].
Bullet 4.10(21/5) and 4.10(22/5).
Move 4.10(16/5) and the associated AARM notes after 4.10(23/5). [This is not
bulleted].
Modify 7.3.2(3/4):
Type_Invariant'Class
This aspect shall be specified by an expression, called an invariant
expression. Type_Invariant'Class may be specified on a
private_type_declaration, or a private_extension_declaration, or a
full_type_declaration for an interface type. Type_Invariant'Class
determines a class-wide type invariant for a tagged type. {[Redundant:
The Type_Invariant'Class aspect is not inherited, but its effects are
additive, as defined below.]}
Modify 7.3.3(2/5):
Default_Initial_Condition
This aspect shall be specified by an expression, called a default
initial condition expression. Default_Initial_Condition may be
specified on a private_type_declaration, a
private_extension_declaration, a formal_private_type_definition, or a
formal_derived_type_definition. {[Redundant: The
Default_Initial_Condition aspect is not inherited, but its effects are
additive, as defined below.]}
Add after 12.5.1(21/3):
In an instance, the implicitly composed and additive aspects (see
13.1.1) of a formal type are those of the actual; for a nonoverridable
aspect, a formal derived type inherits the aspect if the ancestor or
any progenitor has the aspect, according to the rules given in 13.1.
Delete 13.1(15.9/5) [NOTE: it is no longer relevant because
implicitly-composed aspects are not inherited, even for untagged
derived types. Here is what it currently says:
When an aspect that is a subprogram is inherited, the derived type
inherits the aspect in the same way that a derived type inherits a
user-defined primitive subprogram from its parent (see 3.4).]
Modify 13.1.1(18.3/5):
Certain type-related aspects are defined to be /nonoverridable/{; all
such aspects are inherited by derived types according to the rules
given in 13.1. Any legality rule associated with a nonoverridable
aspect is re-checked for the derived type, if the derived type is not
abstract. Certain type-related and subtype-specific aspects are
defined to be /additive/; such aspects are not inherited, but they can
/apply/ to the types derived from, or the subtypes based on, the
original type or subtype, as defined for each such aspect. Finally,
certain type-related aspects are /implicitly composed/; such aspects
are not inherited, but rather a default implementation for a derived
type is provided, as defined for each such aspect, based on that of
its parent type, presuming the aspect for the parent type is available
where the derived type is declared, plus those of any new components
added as part of a type extension.}
Delete 13.13.2(8.1/3) and the associated AARM note (it will be moved below).
Modify 13.13.2(9/3): [Splitting into two paragraphs.]
For {nonderived} elementary types, Read reads (and Write writes) the
number of stream elements implied by the Stream_Size for the type T; the
representation of those stream elements is implementation defined. For
{nonderived} composite types, the Write or Read attribute for each component
(excluding those, if any, that are not components of the nominal type
of the object) is called in canonical order, which is last dimension
varying fastest for an array (unless the convention of the array is
Fortran, in which case it is first dimension varying fastest), and
positional aggregate order for a record. Bounds are not included in
the stream if T is an array type. If T is a discriminated type,
discriminants are included only if they have defaults. If T is a
tagged type, the tag is not included.{
}For type extensions, the Write
or Read attribute for the parent type is called, followed by the Write
or Read attribute of each component of the extension part, in
canonical order. For a limited type extension, if the attribute of the
parent type or any progenitor type of T is available anywhere within
the immediate scope of T, and the attribute of the parent type or the
type of any of the extension components is not available at the
freezing point of T, then the attribute of T shall be directly
specified. {For untagged derived types, the
Write (resp. Read) attribute invokes the corresponding attribute
of the parent type, if the attribute is available
for the parent type.}
Modify 13.13.2(25/3):
For an untagged derived type, {the default implementation of} the
Output (resp. Input) attribute {invokes the corresponding attribute of
the parent type,} [inherited according to the rules given in 13.1] if
the attribute is [[Redundant: specified and]] available for the parent
type[at the point where T is declared]. [For a tagged derived type,
these attributes are not inherited, but rather the default
implementations are used.] {For any other type, the default
implementations of the Output and Input attributes, where available,
execute as follows:}
Delete 13.13.2(25.1/2): [NOTE: Its content has been moved into 25/3 above.]
Modify 13.13.2(42/2):
T is a limited untagged derived type, and the attribute [was inherited]
{is available} for the {parent} type.
Modify 13.13.2(44/2):
The attribute has been specified via an attribute_definition_clause{ or
aspect_specification}, and the attribute_definition_clause{ or
aspect_specification} is visible.
Modify 13.13.2(47/2):
The attribute has been specified via an attribute_definition_clause{ or
aspect_specification}, and the attribute_definition_clause{ or
aspect_specification} is visible.
Modify 13.13.2(49.1/4):
Unless {available for}[inherited from] a parent type, if any, for an
untagged type having a task, protected, or explicitly limited record part,
the default implementation of each of the Read, Write, Input, and Output
attributes raises Program_Error and performs no other action.
!discussion
Almost all of the above wording is intended to clarify the existing
inheritance and reemergence rules, rather than establish new rules.
However, there are two significant changes:
1) We have said that the Put_Image aspects are not inherited, but are
rather implicitly composed. Before we were silent on what happened
with an untagged derived type.
2) We treat user-defined literal aspects as nonoverridable. The current
wording suggests that they are a separate operation, but says that
they are inherited as defined in 13.1. This presumably was referring to
stream-attribute style inheritance, although nonoverridable inheritance
is also (partially) defined there.
We considered using a form of "implicitly composed" inheritance for
user-defined literals. This would have the advantage that an extension could
have the literal operation and the originally associated operation do
different things (which could be necessary if the named operation is useful
user operation in its own right, such as the From_String conversion originally
defined for BigNums). But it would have the disadvantage that for a non-null
type extension, the aspect is required to be re-specified, again, even if
it is to just use the overriding of the previously named primitive. That would
necessary as such functions are required to be overridden, and a similar rule
would be needed for such aspects.
!examples
type T is private
with Integer_Literal => From_String;
function From_String(S : String) return T;
...
type T2 is new T;
overriding
function From_String(S : String) return T2;
The overriding From_String is used for converting integer literals for T2.
In the rejected alternative, the overriding From_String would not be
used, unless you repeat the "with Integer_Literal => From_String" on the
declaration of T2. In this alternative, you would have had the ability to have
T2 use a different operation for converting literals. As defined, you are
limited to using "From_String" in all descendants, because the aspect is
nonoverridable.
!corrigendum 3.2.4(1/3)
Replace the paragraph:
The language-defined predicate aspects Static_Predicate and Dynamic_Predicate
may be used to define properties of subtypes. A predicate specification is an
aspect_specification for one of the two predicate aspects.
General rules for aspects and aspect_specifications are found in
Clause 13 (13.1 and 13.1.1 respectively).
by:
The language-defined predicate aspects Static_Predicate and Dynamic_Predicate
may be used to define properties of subtypes. A predicate specification is an
aspect_specification for one of the two predicate aspects.
General rules for aspects and aspect_specifications are found in
Clause 13 (13.1 and 13.1.1 respectively). The predicate
aspects are assertion aspects (see 11.4.2). The predicate aspects are not
inherited, but their effects are additive, as defined below.
!corrigendum 3.2.4(29.5/4)
Replace the paragraph:
- if S is a first subtype, the value is tested
to determine whether it satisfies the predicates of the parent
and progenitor subtypes (if any) of S (in an arbitrary order);
by:
- if S is a first subtype, the value is tested
to determine whether it satisfies the predicates of the parent
and progenitor subtypes (if any) of S (in an arbitrary order), after a
(view) conversion of the value to the corresponding parent or progenitor
type;
!corrigendum 3.9.2(1/2)
Replace the paragraph:
The primitive subprograms of a tagged type, the subprograms declared by
formal_abstract_subprogram_declarations, and the stream attributes of a
specific tagged type that are available (see 13.13.2) at the end of the
declaration list where the type is declared are called dispatching
operations. A dispatching operation can be called using a statically
determined controlling tag, in which case the body to be executed is
determined at compile time. Alternatively, the controlling tag can be
dynamically determined, in which case the call dispatches to a body that is
determined at run time; such a call is termed a dispatching call. As
explained below, the properties of the operands and the context of a particular
call on a dispatching operation determine how the controlling tag is
determined, and hence whether or not the call is a dispatching call. Run-time
polymorphism is achieved when a dispatching operation is called by a
dispatching call.
by:
The primitive subprograms of a tagged type, the subprograms declared by
formal_abstract_subprogram_declarations, the Put_Image attribute (see 4.10)
of a specific tagged type, and the stream attributes of a
specific tagged type that are available (see 13.13.2) at the end of the
declaration list where the type is declared are called dispatching
operations. A dispatching operation can be called using a statically
determined controlling tag, in which case the body to be executed is
determined at compile time. Alternatively, the controlling tag can be
dynamically determined, in which case the call dispatches to a body that is
determined at run time; such a call is termed a dispatching call. As
explained below, the properties of the operands and the context of a particular
call on a dispatching operation determine how the controlling tag is
determined, and hence whether or not the call is a dispatching call. Run-time
polymorphism is achieved when a dispatching operation is called by a
dispatching call.
!corrigendum 4.2.1(0)
Insert new clause:
** Force a conflict; the actual changes are in the conflict file. **
!corrigendum 4.10(0)
Insert new clause:
** Force a conflict; the actual changes are in the conflict file. **
!corrigendum 7.3.2(3/4)
Replace the paragraph:
- Type_Invariant'Class
-
This aspect shall be specified by an expression, called an
invariant expression. Type_Invariant'Class may be specified on a
private_type_declaration, a private_extension_declaration, or
a full_type_declaration for an interface type. Type_Invariant'Class
determines a class-wide type invariant for a tagged type.
by:
- Type_Invariant'Class
-
This aspect shall be specified by an expression, called an
invariant expression. Type_Invariant'Class may be specified on a
private_type_declaration, a private_extension_declaration, or
a full_type_declaration for an interface type. Type_Invariant'Class
determines a class-wide type invariant for a tagged type. The
Type_Invariant'Class aspect is not inherited, but its effects are
additive, as defined below.
!corrigendum 7.3.3(0)
Insert new clause:
** Force a conflict; the actual changes are in the conflict file. **
!corrigendum 12.5.1(21/3)
Insert after the paragraph:
In an instance, the copy of an implicit declaration of a
primitive subprogram of a formal derived type declares
a view of the corresponding primitive subprogram of the ancestor or progenitor
of the formal derived type, even if this primitive has been overridden for the
actual type and even if it is never declared for the actual type. When the
ancestor or progenitor of the formal derived type is itself a formal type, the
copy of the implicit declaration declares a view of the corresponding copied
operation of the ancestor or progenitor. In the case of a formal private
extension, however, the tag of the formal type is that of the actual type, so
if the tag in a call is statically determined to be that of the formal type,
the body executed will be that corresponding to the actual type.
the new paragraph:
In an instance, the implicitly composed and
additive aspects (see 13.1.1) of a formal
type are those of the actual; for a nonoverridable
aspect, a formal derived type inherits the aspect if the ancestor or
any progenitor has the aspect, according to the rules given in 13.1.
!corrigendum 13.1(15.2/2)
Delete the paragraph:
When an aspect that is a subprogram is inherited, the derived type inherits the
aspect in the same way that a derived type inherits a user-defined primitive
subprogram from its parent (see 3.4).
!corrigendum 13.1.1(18.2/4)
Replace the paragraph:
Certain type-related aspects are defined to be nonoverridable; all such
aspects are specified using an aspect_definition that is a name.
by:
Certain type-related aspects are defined to be nonoverridable; all
such aspects are inherited by derived types according to the rules
given in 13.1. Any legality rule associated with a nonoverridable
aspect is re-checked for the derived type, if the derived type is not
abstract. Certain type-related and subtype-specific aspects are
defined to be additive; such aspects are not inherited, but they can
apply to the types derived from, or the subtypes based on, the
original type or subtype, as defined for each such aspect. Finally,
certain type-related aspects are implicitly composed; such aspects
are not inherited, but rather a default implementation for a derived
type is provided, as defined for each such aspect, based on that of
its parent type, presuming the aspect for the parent type is available
where the derived type is declared, plus those of any new components
added as part of a type extension.
!corrigendum 13.13.2(8.1/3)
Delete the paragraph:
For an untagged derived type, the Write (resp. Read) attribute is inherited
according to the rules given in 13.1 if the attribute is specified and
available for the parent type at the point where T is declared. For
a tagged derived type, these attributes are not inherited, but rather the
default implementations are used.
!corrigendum 13.13.2(9/3)
Replace the paragraph:
For elementary types, Read reads (and Write writes) the number of stream
elements implied by the Stream_Size for the type T; the representation of
those stream elements is implementation defined.
For composite types, the Write or Read attribute for
each component is called in canonical order, which is last dimension varying
fastest for an array (unless the convention of the array is
Fortran, in which case it is first dimension varying fastest),
and positional aggregate order for a record. Bounds are
not included in the stream if T is an array type. If T is a
discriminated type, discriminants are included only if they have defaults.
If T is a tagged type, the tag is not included. For type extensions, the
Write or Read attribute for the parent type is called, followed by the Write
or Read attribute of each component of the extension part, in canonical order.
For a limited type extension, if the attribute of the parent type or any
progenitor type of T is available anywhere within the immediate scope of
T, and the attribute of the parent type or the type of any of the extension
components is not available at the freezing point of T, then the attribute
of T shall be directly specified.
by:
For nonderived elementary types, Read reads (and Write writes) the number of
stream elements implied by the Stream_Size for the type T; the
representation of those stream elements is implementation defined.
For nonderived composite types, the Write or Read attribute for each component
(excluding those, if any, that are not components of the nominal type of the
object) is called in canonical order, which is last dimension varying
fastest for an array (unless the convention of the array is
Fortran, in which case it is first dimension varying fastest),
and positional aggregate order for a record. Bounds are
not included in the stream if T is an array type. If T is a
discriminated type, discriminants are included only if they have defaults.
If T is a tagged type, the tag is not included.
For type extensions, the
Write or Read attribute for the parent type is called, followed by the Write
or Read attribute of each component of the extension part, in canonical order.
For a limited type extension, if the attribute of the parent type or any
progenitor type of T is available anywhere within the immediate scope of
T, and the attribute of the parent type or the type of any of the extension
components is not available at the freezing point of T, then the attribute
of T shall be directly specified. For untagged derived types, the
Write (resp. Read) attribute invokes the corresponding attribute
of the parent type, if the attribute is available for the parent type.
!corrigendum 13.13.2(25/3)
Replace the paragraph:
For an untagged derived type, the Output (resp. Input) attribute is inherited
according to the rules given in 13.1 if the attribute is specified and
available for the parent type at the point where T is declared. For a
tagged derived type, these attributes are not inherited, but rather the
default implementations are used.
by:
For an untagged derived type, the default implementation of
the Output (resp. Input) attribute invokes the corresponding attribute of
the parent type, if the attribute is available for the parent type. For
any other type, the default implementations of the Output and Input
attributes, where available, execute as follows:
!corrigendum 13.13.2(25.1/2)
Delete the paragraph:
The default implementations of the Output and Input attributes, where
available, execute as follows:
!corrigendum 13.13.2(42/2)
Replace the paragraph:
- T is a limited untagged derived type, and the attribute was
inherited for the type.
by:
- T is a limited untagged derived type, and the attribute is
available for the parent type.
!corrigendum 13.13.2(44/2)
Replace the paragraph:
- The attribute has been specified via an
attribute_definition_clause, and the attribute_definition_clause
is visible.
by:
- The attribute has been specified via an
attribute_definition_clause or aspect_specification, and the
attribute_definition_clause or aspect_specification is visible.
!corrigendum 13.13.2(47/2)
Replace the paragraph:
- the attribute has been specified via an
attribute_definition_clause, and the attribute_definition_clause
is visible; or
by:
- the attribute has been specified via an
attribute_definition_clause or aspect_specification, and the
attribute_definition_clause or aspect_specification is visible; or
!corrigendum 13.13.2(49.1/4)
Replace the paragraph:
Unless inherited from a parent type, if any, for an untagged type having a
task, protected, or explicitly limited record part, the default implementation
of each of the Read, Write, Input, and Output attributes raises Program_Error
and performs no other action.
by:
Unless available for a parent type, if any, for an untagged type having a
task, protected, or explicitly limited record part, the default implementation
of each of the Read, Write, Input, and Output attributes raises Program_Error
and performs no other action.
!ASIS
No ASIS effect.
!ACATS test
ACATS B- and C-Tests are needed to check that Put_Image works properly
for derived types. We also need ACATS B- and C-Tests are needed to
check that the user-defined literal aspects are nonoverrideable.
No tests are needed for other aspects as no semantic change is intended.
!appendix
From: Randy Brukardt
Sent: Monday, February 1, 2021 09:23 PM
In AI12-0419-1, the placement of the untagged derived type rule (4.10(7/5))
was in the middle of rules that apply only to elementary types. Tucker also
proposed moving the record type rules to a location under a heading "for all
elementary types". The next elementary record type I encounter will be the
first. :-) Some reorganization is needed to fix this.
This mistake happened because the rules 4.10(8/5) to 4.10(12/5) are all
underneath the heading 4.10(7/5), but that was not obvious as there is no
bullets or indentation used. After discussion with Tucker, we decided that
most of these paragraphs should have bullets.
These changes rearrange (and indent and bullet) many of the paragraphs in
4.10, however, the actual wording is barely changed (and most of those
changes were in the original, approved, AI).
This was processed as an editorial review change to AI12-0419-1. No action is
required unless you want to object to some part of this change. A detailed
list of changes and the actual !wording for the AI follows this note.
---
(1) Split 4.10(5/5) into two parts.
(2) Put the new paragraph about untagged derived types in the middle of that
paragraph.
(3) Bulleted the subsidiary paragraphs to the "For elementary types..." so it
is obvious that they are a different level than the others.
(4) Reorganized what was 4.10(15/5) to start with "For all composite types...",
as it is supposed to be a blanket rule but it is getting lost - following
the intended reading of this section, it would only belong to array types.
(5) Added an intro "For a specific, nonderived composite type:" as a
counterpart to the elementary type rule. Moved the type extension paragraph
(which was 4.10(17/5) & 4.10(18/5)) before this introduction.
(6) Bulleted the subsidiary paragraphs to this new header. (paragraphs that
were 4.10(15/5), 4.10(13/5), 4.10(14/5) [not bulleted, it is part of the
preceding paragraph], 4.10(21/5), 4.10(22/5) [also not bulleted], 4.10(21/5),
4.10(22/5), and 4.10(23/5) [not bulleted, of course]).
(7) Put the class-wide paragraph (was 4.10(16/5)) at the end of all of this (not
bulleted or indented).
---
Here is the entire new !wording for these paragraphs.
[See version /03 of this AI - Editor.]
---
A following message shows this entire part of the clause as reformatted (in
HTML). [Not recorded here - Editor.]
****************************************************************
From: Randy Brukardt
Sent: Thursday, February 4, 2021 01:53 AM
In AI12-0419-1, Tucker had recommended a reordering of parts of the paragraphs
13.13.2(8.1/3), 13.13.2(8.2/2), 13.13.2(9/3). There are a couple of issues
raised by this reordering, the most important of which is that a use of the
term "canonical order" would appear before the definition of the term.
It occurred to me that much less reordering is needed to get the correct
result, we just need a few strategic additions of "nonderived", and the
addition of a bit of 13.13.2(8.1/3). When Tucker reviewed these changes,
he suggested splitting 13.13.2(9/3) in half, as it has grown too large to
be comfortably readable.
Thus, I'm replacing the changes in the AI for 13.13.2(8.1/3), 13.13.2(8.2/2),
13.13.2(9/3) with the following:
Delete 13.13.2(8.1/3) and the associated AARM note (it will be moved below).
Modify 13.13.2(9/3): [Splitting into two paragraphs.]
For {nonderived} elementary types, Read reads (and Write writes) the
number of stream elements implied by the Stream_Size for the type T; the
representation of those stream elements is implementation defined. For
{nonderived} composite types, the Write or Read attribute for each component
(excluding those, if any, that are not components of the nominal type
of the object) is called in canonical order, which is last dimension
varying fastest for an array (unless the convention of the array is
Fortran, in which case it is first dimension varying fastest), and
positional aggregate order for a record. Bounds are not included in
the stream if T is an array type. If T is a discriminated type,
discriminants are included only if they have defaults. If T is a
tagged type, the tag is not included.{
}For type extensions, the Write
or Read attribute for the parent type is called, followed by the Write
or Read attribute of each component of the extension part, in
canonical order. For a limited type extension, if the attribute of the
parent type or any progenitor type of T is available anywhere within
the immediate scope of T, and the attribute of the parent type or the
type of any of the extension components is not available at the
freezing point of T, then the attribute of T shall be directly
specified. {For untagged derived types, the
Write (resp. Read) attribute invokes the corresponding attribute
of the parent type, if the attribute is available
for the parent type.}
[Note: Paragraph 13.13.2(8.2/2) is unmodified by these changes and thus is no
longer mentioned in the AI.]
---
There are a couple of other minor issues. The definition here is based on
"availability", which is based on visibility of the
attribute_definition_clause or aspect_specification. The old definition was
based on inheritance at the point of the type declaration. This difference
is a minor extension, in that a type derived from a private type can have a
stream attribute available when the full type of the parent is visible. This
can happen in child packages, and avoids an anomoly where the full definitions
of all the types are visible but the stream attributes still cannot be used.
In order that all available stream attributes are well-defined, the wording
"at the point of the type T" was dropped from both 13.13.2(9/3) [that was done
above] and from 13.13.2(25/2).
---
13.13.2(49.1/4) has a left-over "inherited from"; this is replaced by
"available for".
---
Finally, the definition of availability includes the following:
The attribute has been specified via an attribute_definition_clause, and the
attribute_definition_clause is visible.
However, there is no similar rule for aspect_specifications. We updated the
definition of "visibility" to include aspect_specifications when those were
introduced in Ada 2012. But somehow we never updated the rules that *used*
that definition. I'd guess that someone thought that the usual equivalence was
good enough; but this rule is in terms of the syntax definition, and there is
certainly no equivalence of syntax between attribute_definition_clauses and
aspect_specifications.
So, I replaced 13.13.2(44/2) and 13.13.2(47/2) with:
The attribute has been specified via an attribute_definition_clause{ or
aspect_specification}, and the attribute_definition_clause{ or
aspect_specification} is visible.
---
I've processed all of these as Editorial Review changes on AI12-0419-1. These
changes are all making the intent of the approved AI explicit; there is no
change in semantics intended.
I'll note that anyone can request a Letter Ballot if they feel the changes are
too extensive.
P.S. I'm finally done with this AI, which I think is the last nasty one.
****************************************************************
From: Tucker Taft
Sent: Thursday, February 4, 2021 08:36 AM
Looks good, Randy. Nice to avoid the reordering of all of the paragraphs.
****************************************************************
Questions? Ask the ACAA Technical Agent