!standard 4.3.1(17.3/5) 21-01-20 AI12-0418-1/05 !standard 4.3.3(10) !standard 4.3.5(76/5) !standard 4.5.2(3.1/4) !standard 5.5.2(10.2/5) !standard 6.1.1(3/3) !standard 6.1.1(5/3) !standard 6.1.1(7/5) !standard 6.1.1(8/3) !standard 6.5(5.1/5) !standard 6.5(8/4) !standard 6.5.1(1/5) !standard 9.7.4(14/4) !standard 12.3(11) !standard 12.7(4.5/3) !class binding interpretation 20-12-14 !status Amendment 1-2012 20-12-14 !status ARG Approved 15-0-0 21-01-20 !status work item 20-12-14 !status received 20-12-14 !priority Low !difficulty Easy !qualifier Omission !subject Presentation issues from Draft 26 review - part 3 !summary Various wording issues were noted by reviewers of Draft 26. !question (1) 9.7.4(14/4) talks about "abort completion points", which is a forward reference to 9.8. Typically, we have a cross-reference for forward references. Should one be added here? (Yes.) (2) 12.3(11) needs a comma in "In a generic unit Legality Rules ..."; the two other clauses have commas before "Legality Rules" so this one is inconsistent. Should it be added? (Yes.) (3) 5.5.2(10.2/5) uses commas oddly, and is hard to read because of its size. Should the comma use be improved, and the paragraph split? (Yes.) (4) In 4.3.1(17.3/5), the parenthesized (box) is weird. Other similar rules either do not include box at all (4.3.5(26/5), 12.7(4.5/3)) or include box in the narrative text (4.3.4(11/5)), or even only use "box" but not <> (12.6(10)). Should this be reworded? (Yes.) (5) 12.7(4.5/3) ends with "must be given by <> as well". ISO does not allow the use of the word "must" in normative text, and "as well" seems informal. Should this be reworded? (Yes.) (6) In 4.3.3(10), the wording of the "redundant" sentence is extremely pedantic and hard to follow. Should this be reworded? (Yes.) (7) The example 4.3.5(76/5) is pretty suboptimal as the conditional inside the loop is not necessary. Should a simpler form be used? (Yes.) (8) In 4.5.2(3.1/4), "for" should be "of" for consistency, since the following sentence uses "of" instead of "for". Change this? (Yes.) (9) In 6.1.1(7/5), the phrase "formal access parameter (or S'Result) of type access-to-T" could be read to apply to all functions that return an access type, not just those that are anonymous. Should this be reworded? (Yes.) (10) 6.1.1(8/3) talks about the expected type of an Old reference. Similar wording in 4.5.7 for conditional expressions includes "expected for some class of types". Do we need to mention this case here? (Yes.) (11) 6.5(5.1/5) would be improved with an "(if any)" to make it clear that no expression need exist. Should we do this? (Yes.) (12) 6.5(8/4) should say "the expression of the return statement"; AI12-0173-1 made the To Be Honest note unnecessary if we use the full term. Do it? (Yes.) (13) 6.5.1(1/5) appears to give an exhaustive list of reasons that a subprogram might not return, but clearly other reasons exist (such as blocking on an entry call forever). Should this be made more clearly examples? (Yes.) (14) 6.1.1(3/3) and 6.1.1(5/3) would be clearer if they said that they only apply to dispatching operations. This is redundant with the Legality Rules of 13.1.1, so it does not change anything. Do this? (Yes.) !recommendation (1) Add (see 9.8) after "abort completion points". (2) Add the comma. (3) Add one comma, remove two others, replace "having" with "that has" (2 places), and split into three parts. (4) Move box in front of "compound delimiter". (5) Replace "must" with "shall also", and delete "as well". (6) Remove the phrase "where an array_aggregate is permitted" and replace "the aggregate" with "an array_aggregate". (7) Replace the single loop with two loops, which is closer to the actual expansion. (8) Replace "for" with "of". (9) Add "for an access result" after the second S'Result. (10) Add "(or class of types)". Also, there are two syntax terms in the wrong font in this paragraph. (11) Add "(if any)". (12) Add " of the return statement". (13) Add ", for example,". (14) Replace "an operation" with "a dispatching operation" in both paragraphs. !wording [Editor's note: These changes were applied to Draft 28 of the Ada 202x RM, even though they have not yet been approved, in order that that draft be as accurate as possible.] Modify 4.3.1(17.3/5): * use the {box} compound delimiter <> [(box)] rather than an expression; Modify 4.3.3(10): An others choice is allowed for an array_aggregate only if an applicable index constraint applies to the array_aggregate. An applicable index constraint is a constraint provided by certain contexts[ where an array_aggregate is permitted] that can be used to determine the bounds of the array value specified by [the aggregate]{an array_aggregate}. Each of the following contexts (and none other) defines an applicable index constraint: Replace 4.3.5(76/5): -- Is equivalent (assuming set semantics) to: S := Empty_Set; for Item in -5 .. 5 loop if Item /= 0 then Include (S, Item); end if; end loop; with: -- Is equivalent (assuming set semantics) to: S := Empty_Set; for Item in 1 .. 5 loop Include (S, Item) end loop; for Item in -5 .. -1 loop Include (S, Item) end loop; Modify 4.5.2(3.1/4): If the tested type is tagged, then the tested_simple_expression shall resolve to be of a type that is convertible (see 4.6) to the tested type; if untagged, the expected type {of}[for] the tested_simple_expression is the tested type. The expected type of a choice_simple_expression in a membership_choice, and of a simple_expression of a range in a membership_choice, is the tested type of the membership operation. Modify 5.5.2(10.2/5): [This splits it into three parts, and makes other changes as noted:] Upon return from Split_Into_Chunks, the actual number of chunks for the loop is determined by calling the Chunk_Count operation of the iterator, at which point one logical thread of control is initiated for each chunk, with an associated chunk index in the range from one to the actual number of chunks.{ }Within each logical thread of control, a loop parameter is created. If a chunk_specification with a discrete_subtype_definition is present in the associated parallel construct, then a chunk parameter is created[,] and initialized with a value from the discrete subtype defined by the discrete_subtype_definition, so that the order of the chosen chunk parameter values correspond to the order of the chunk indices associated with the logical threads of control. The operation First of the iterator type {that has}[having] a Chunk parameter is called on the loop iterator, with Chunk initialized from the corresponding chunk index, to produce the initial value for the loop parameter. If the result of calling Has_Element on this initial value is False, then the execution of the logical thread of control is complete. Otherwise, the sequence_of_statements is conditionally executed{,} and then the Next operation of the iterator type {that has}[having] a Chunk parameter is called[,] with the loop iterator, the current value of the loop parameter, and the corresponding chunk index, to produce the next value to be assigned to the loop parameter. This repeats until the result of calling Has_Element on the loop parameter is False, or the associated parallel construct is left as a consequence of a transfer of control.{ }In the absence of a transfer of control, the associated parallel construct of a parallel generalized iterator is complete when all of its logical threads of control are complete. Modify 6.1.1(3/3): This aspect specifies a class-wide precondition for {a dispatching}[an] operation of a tagged type and its descendants; it shall be specified by an expression, called a class-wide precondition expression. If not specified for an entity, then if no other class-wide precondition applies to the entity, the class-wide precondition expression for the entity is the enumeration literal True. Modify 6.1.1(5/3): This aspect specifies a class-wide postcondition for {a dispatching}[an] operation of a tagged type and its descendants; it shall be specified by an expression, called a class-wide postcondition expression. If not specified for an entity, the class-wide postcondition expression for the entity is the enumeration literal True. Modify 6.1.1(7/5): Within the expression for a Pre'Class or Post'Class aspect for a primitive subprogram S of a tagged type T, a name name that denotes a formal parameter (or S'Result) of type T is interpreted as though it had a (notional) nonabstract type NT that is a formal derived type whose ancestor type is T, with directly visible primitive operations. Similarly, a name name that denotes a formal access parameter (or S'Result{ for an access result}) of type access-to-T is interpreted as having type access-to-NT access-to-T'Class. The result of this interpretation is that the only operations that can be applied to such names are those defined for such a formal derived type. Modify 6.1.1(8/3): For an attribute_reference with attribute_designator Old, if the attribute reference has an expected type {(or class of types)} or shall resolve to a given type, the same applies to the prefix; otherwise, the prefix shall be resolved independently of context. Modify 6.5(5.1/5): The expression of an extended_return_statement is the expression {(if any)} of the extended_return_object_declaration of the extended_return_statement. Add an AARM Ramification: The /expression of a return statement/ is either the expression of a simple_return_statement or the expression of an extended_return_statement as defined above. Modify 6.5(8/4): If the result type of a function is a specific tagged type, the tag of the return object is that of the result type. If the result type is class-wide, the tag of the return object is that of the value of the expression{ of the return statement}, unless the return object is defined by an extended_return_object_declaration with a subtype_indication that is specific, in which case it is that of the type of the subtype_indication. A check is made that the master of the type identified by the tag of the result includes the elaboration of the master that elaborated the function body. If this check fails, Program_Error is raised. Delete AARM 6.5(8.d.1/4). Modify 6.5.1(1/5): Specifying aspect No_Return to have the value True indicates that a subprogram cannot return normally; it may{, for example,} propagate an exception or loop forever. Modify 9.7.4(14/4): Note that these examples presume that there are abort completion points {(see 9.8) }within the execution of the abortable_part. Modify 12.3(11): In a generic unit{,} Legality Rules are enforced at compile time of the generic_declaration and generic body, given the properties of the formals. In the visible part and formal part of an instance, Legality Rules are enforced at compile time of the generic_instantiation, given the properties of the actuals. In other parts of an instance, Legality Rules are not enforced; this rule does not apply when a given rule explicitly specifies otherwise. Modify 12.7(4.5/3): If a formal_package_association for a formal type T of the template is given by <>, then the formal_package_association for any other generic_formal_parameter_declaration of the template that mentions T directly or indirectly {shall also}[must] be given by <>[ as well]. !discussion (See !recommendation.) !corrigendum 4.3.1(17.1/2) @dinsa A @fa for a discriminant without a @fa shall have an @fa rather than <@>. @dinss A @fa of the @fa of a @fa shall not: @xbullet rather than an @fa;> @xbullet of a limited type;> @xbullet; or> @xbullet that is an @b choice.> For a @fa, no two @i@fas shall denote components declared within different @fas of the same @fa. !corrigendum 4.3.3(10) @drepl An @b choice is allowed for an @fa only if an @i applies to the @fa. An applicable index constraint is a constraint provided by certain contexts where an @array_aggregate> is permitted that can be used to determine the bounds of the array value specified by the aggregate. Each of the following contexts (and none other) defines an applicable index constraint: @dby An @b choice is allowed for an @fa only if an @i applies to the @fa. An applicable index constraint is a constraint provided by certain contexts that can be used to determine the bounds of the array value specified by an @fa. Each of the following contexts (and none other) defines an applicable index constraint: !corrigendum 4.3.5(0) @dinsc See the conflict file for the changes. !corrigendum 4.5.2(3.1/4) @drepl If the tested type is tagged, then the @i@fa shall resolve to be of a type that is convertible (see 4.6) to the tested type; if untagged, the expected type for the @i@fa is the tested type. The expected type of a @i@fa in a @fa, and of a @fa of a @fa in a @fa, is the tested type of the membership operation. @dby If the tested type is tagged, then the @i@fa shall resolve to be of a type that is convertible (see 4.6) to the tested type; if untagged, the expected type of the @i@fa is the tested type. The expected type of a @i@fa in a @fa, and of a @fa of a @fa in a @fa, is the tested type of the membership operation. !corrigendum 5.5.2(10/3) @drepl For a generalized iterator, the loop parameter is created, the @i@fa is evaluated, and the denoted iterator object becomes the @i. In a forward generalized iterator, the operation First of the iterator type is called on the loop iterator, to produce the initial value for the loop parameter. If the result of calling Has_Element on the initial value is False, then the execution of the @fa is complete. Otherwise, the @fa is executed and then the Next operation of the iterator type is called with the loop iterator and the current value of the loop parameter to produce the next value to be assigned to the loop parameter. This repeats until the result of calling Has_Element on the loop parameter is False, or the loop is left as a consequence of a transfer of control. For a reverse generalized iterator, the operations Last and Previous are called rather than First and Next. @dby *** The replacement text is found in the conflict file *** !corrigendum 6.1.1(3/3) @drepl @xhang<@xterm This aspect specifies a class-wide precondition for an operation of a tagged type and its descendants; it shall be specified by an @fa, called a @i. If not specified for an entity, then if no other class-wide precondition applies to the entity, the class-wide precondition expression for the entity is the enumeration literal True.> @dby @xhang<@xterm This aspect specifies a class-wide precondition for a dispatching operation of a tagged type and its descendants; it shall be specified by an @fa, called a @i. If not specified for an entity, then if no other class-wide precondition applies to the entity, the class-wide precondition expression for the entity is the enumeration literal True.> !corrigendum 6.1.1(5/3) @drepl @xhang<@xterm This aspect specifies a class-wide postcondition for an operation of a tagged type and its descendants; it shall be specified by an @fa, called a @i. If not specified for an entity, the class-wide postcondition expression for the entity is the enumeration literal True.> @dby @xhang<@xterm This aspect specifies a class-wide postcondition for a dispatching operation of a tagged type and its descendants; it shall be specified by an @fa, called a @i. If not specified for an entity, the class-wide postcondition expression for the entity is the enumeration literal True.> !corrigendum 6.1.1(7/4) @drepl Within the expression for a Pre'Class or Post'Class aspect for a primitive subprogram @i of a tagged type @i, a @fa that denotes a formal parameter (or @i'Result) of type @i is interpreted as though it had a (notional) type @i that is a formal derived type whose ancestor type is @i, with directly visible primitive operations. Similarly, a @fa that denotes a formal access parameter (or @i'Result) of type access-to-@i is interpreted as having type access-to-@i. The result of this interpretation is that the only operations that can be applied to such @fas are those defined for such a formal derived type. @dby Within the expression for a Pre'Class or Post'Class aspect for a primitive subprogram @i of a tagged type @i, a @fa that denotes a formal parameter (or @i'Result) of type @i is interpreted as though it had a (notional) nonabstract type @i that is a formal derived type whose ancestor type is @i, with directly visible primitive operations. Similarly, a @fa that denotes a formal access parameter (or @i'Result for an access result) of type access-to-@i is interpreted as having type access-to-@i. The result of this interpretation is that the only operations that can be applied to such @fas are those defined for such a formal derived type. !corrigendum 6.1.1(8/3) @drepl For an attribute_reference with attribute_designator Old, if the attribute reference has an expected type or shall resolve to a given type, the same applies to the @fa; otherwise, the @fa shall be resolved independently of context. @dby For an @fa with @fa Old, if the attribute reference has an expected type (or class of types) or shall resolve to a given type, the same applies to the @fa; otherwise, the @fa shall be resolved independently of context. !corrigendum 6.5(5/3) @drepl A function body shall contain at least one return statement that applies to the function body, unless the function contains @fas. A @fa shall include an @fa if and only if it applies to a function body. An @fa shall apply to a function body. An @fa with the reserved word @b shall include an @fa. @dby A function body shall contain at least one return statement that applies to the function body, unless the function contains @fas. A @fa shall include an @fa if and only if it applies to a function body. An @fa shall apply to a function body. An @fa with the reserved word @b shall include an @fa. The @fa<@i> @i @fa<@i> is the @fa (if any) of the @fa of the @fa. !corrigendum 6.5(8/4) @drepl If the result type of a function is a specific tagged type, the tag of the return object is that of the result type. If the result type is class-wide, the tag of the return object is that of the value of the @fa, unless the return object is defined by an @fa with a @fa that is specific, in which case it is that of the type of the @fa. A check is made that the master of the type identified by the tag of the result includes the elaboration of the master that elaborated the function body. If this check fails, Program_Error is raised. @dby If the result type of a function is a specific tagged type, the tag of the return object is that of the result type. If the result type is class-wide, the tag of the return object is that of the value of the @fa of the return statement, unless the return object is defined by an @fa with a @fa that is specific, in which case it is that of the type of the @fa. A check is made that the master of the type identified by the tag of the result includes the elaboration of the master that elaborated the function body. If this check fails, Program_Error is raised. !corrigendum 6.5.1(1/3) @drepl Specifying aspect No_Return to have the value True indicates that a procedure cannot return normally; it may propagate an exception or loop forever. @dby Specifying aspect No_Return to have the value True indicates that a subprogram cannot return normally; it may, for example, propagate an exception or loop forever. !corrigendum 9.7.4(14/4) @drepl Note that these examples presume that there are abort completion points within the execution of the @fa. @dby Note that these examples presume that there are abort completion points (see 9.8) within the execution of the @fa. !corrigendum 12.3(11) @drepl In a generic unit Legality Rules are enforced at compile time of the @fa and generic body, given the properties of the formals. In the visible part and formal part of an instance, Legality Rules are enforced at compile time of the @fa, given the properties of the actuals. In other parts of an instance, Legality Rules are not enforced; this rule does not apply when a given rule explicitly specifies otherwise. @dby In a generic unit, Legality Rules are enforced at compile time of the @fa and generic body, given the properties of the formals. In the visible part and formal part of an instance, Legality Rules are enforced at compile time of the @fa, given the properties of the actuals. In other parts of an instance, Legality Rules are not enforced; this rule does not apply when a given rule explicitly specifies otherwise. !corrigendum 12.7(4.5/3) @drepl @xbullet for a formal type @i of the template is given by <@>, then the @fa for any other @fa of the template that mentions @i directly or indirectly must be given by <@> as well.> @dby @xbullet for a formal type @i of the template is given by <@>, then the @fa for any other @fa of the template that mentions @i directly or indirectly shall also be given by <@>.> !ASIS No ASIS effect. !ACATS test No ACATS tests should be needed, none of these changes change any semantics. !appendix From the AARM review of John Barnes, September 2020 9.7.4(14/4) I would add (see 9.8) but not essential. It is a forward reference. 12.3(11) Please put a comma thus "In a generic unit, Legality Rules…" **************************************************************** From the AARM review of Justin Squirek, October 2020 ----------- -- 5.5.2 -- ----------- 10.2/5: This section reads strangely to me and many commas seem out of place (I could be wrong though). I have included the entire section here with suggested improvements surrounded by square brackets: "Upon return from Split_Into_Chunks, the actual number of chunks for the loop is determined by calling the Chunk_Count operation of the iterator, at which point one logical thread of control is initiated for each chunk [removed comma] with an associated chunk index in the range from one to the actual number of chunks. Within each logical thread of control [removed comma] a loop parameter is created. If a chunk_specification with a discrete_subtype_definition is present in the associated parallel construct, then a chunk parameter is created [removed comma] and initialized with a value from the discrete subtype defined by the discrete_subtype_definition, so that the order of the chosen chunk parameter values correspond to the order of the chunk indices associated with the logical threads of control. The operation First of the iterator type [containing] a Chunk parameter [gets] called on the loop iterator, with Chunk initialized from the corresponding chunk index, to produce the initial value for the loop parameter. If the result of calling Has_Element on this initial value is False, then the execution of the logical thread of control is complete. Otherwise, the sequence_of_statements is conditionally executed and then the Next operation of the iterator type [containing] a Chunk parameter [gets] called [comma removed] with the loop iterator, the current value of the loop parameter, and the corresponding chunk index [comma removed] to produce the next value to be assigned to the loop parameter. This repeats until the result of calling Has_Element on the loop parameter is False, or the associated parallel construct is left as a consequence of a transfer of control. In the absence of a transfer of control, the associated parallel construct of a parallel generalized iterator is complete when all of its logical threads of control are complete." **************************************************************** Editor's response to the above: (January 7, 2021) First, changing "is" to "gets" (two places) does not seem to be an improvement. It's inconsistent with common usage (in particular, in paragraph 13/5 of this same subclause) and seems informal to me as well. No change there. Second, changing "having" to "contains" (also two places) seems strange to me. Subprograms don't "contain" parameters, they just have them. OTOH, the wording "having" is weird as well, a different word might be better. But I haven't been able to find a better word, so in the absence of that, I'm not going to change this. Third, there does seem to be some unnecessary commas in here. Tucker admits that he overuses commas in his writing, so we agreed to give the text to Gary for tie-breaking. As of this writing, I haven't heard back from Gary, so I'll process this paragraph in the presentation changes so that we call see it and can discuss it again if needed. **************************************************************** From: Gary Dismukes Sent: Thursday, January 7, 2021 11:49 AM [Just the relevant parts of a private e-mail - Editor.] > > 10.2/5: This section reads strangely to me and many commas seem out > > of place (I could be wrong though). I have included the entire > > section here with suggested improvements surrounded by square > > brackets: > > > > "Upon return from Split_Into_Chunks, the actual number of chunks for > > the loop is determined by calling the Chunk_Count operation of the > > iterator, at which point one logical thread of control is initiated > > for each chunk [removed comma] with an associated chunk index in the > > range from one to the actual number of chunks. Without the comma this could be read as meaning "for each chunk that has an associated chunk index" (with => that has), which I don't think is intended. So to me the comma seems helpful. > Within each logical thread of control [removed > > comma] a loop parameter is created. If a chunk_specification with a Normally I think we would use a comma here, to mark off the subsidiary lead-in clause, but it maybe feels a bit heavy. Why not reverse the sentence parts: A loop parameter is created within each logical thread of control. I think that reads better and needs no comma. > > discrete_subtype_definition is present in the associated parallel > > construct, then a chunk parameter is created [removed comma] and > > initialized with a value from the discrete subtype defined by the > > discrete_subtype_definition, I think this is OK without the comma, though I somewhat prefer the comma. Without the comma it could be read as "is created with a value and initialized with a value ...", and the comma avoids that potential reading, though it's probably clear enough what's meant and unlikely to be interpreted that way. > > so that the order of the chosen chunk parameter values correspond to > > the order of the chunk indices associated with the logical threads of control. > > The operation First of the iterator type [containing] a Chunk > > parameter [gets] called on the loop iterator, with Chunk initialized > > from the corresponding chunk index, to produce the initial value for > > the loop parameter. If the result of calling Has_Element on this > > initial value is False, then the execution of the logical thread of control is complete. > > Otherwise, the sequence_of_statements is conditionally executed and > > then I would add a comma before the "and then" above (normal rule in English for separating parts that can be read as sentences on their own). > > the > > Next operation of the iterator type [containing] a Chunk parameter > > [gets] called [comma removed] with the loop iterator, the current > > value of the I agree with removing the indicated comma. > > loop > > parameter, and the corresponding chunk index [comma removed] to > > produce the The comma may not be strictly needed I suppose, but to me it reads a little better with it. After the lengthy comma-separated conjunctions, to me it seems to parse more easily with the comma (a chance to catch one's breath...), but I don't feel super strongly about that. I could even see putting the long conjunction in parentheses: ... called (with the ..., the ..., and the ...) to produce... but I won't suggest that. :) > > next value to be assigned to the loop parameter. This repeats until > > the result of calling Has_Element on the loop parameter is False, or > > the associated parallel construct is left as a consequence of a > > transfer of control. In the absence of a transfer of control, the > > associated parallel construct of a parallel generalized iterator is > > complete when all of its logical threads of control are complete." > > > > ============ > > > > He doesn't really show the original wording here. He seems to be > > right that there are unnecessary commas in here (whether all of them > > are unnecessary is less clear -- but there sure are a lot of > > commas!). I'm less sure about the word changes, they are confusing > > to me. Let me put the changes he suggests for one of the sentences > > above into conventional ARG form: > > > > The operation First of the iterator type {containing}[having] a Chunk > > parameter {gets}[is] called on the loop iterator, with Chunk initialized > > from the corresponding chunk index, to produce the initial value for the > > loop parameter. > > > > I think the original form [in square brackets here] is better; > > that's especially true with "is called" as opposed to "gets called". "is called" > > is I agree that it should be "is called" rather that "gets called". > > also consistent with the existing Ada 2012 wording [para 13/5] > > (which is heavily modified, but not that part). I'm less annoyed by > > the other suggestion, although I don't think subprograms "contain" > > parameters as much as "having" parameters. Right. Maybe "that has" instead of "having"? (The first part of that sentence is still a bit awkward, as it could be read as saying that the iterator type rather than the operation has the parameter, but I don't have a good suggestion for avoiding that.) **************************************************************** From: Tucker Taft Sent: Thursday, January 7, 2021 12:01 PM [Another private e-mail - Editor.] ... > Why not reverse the sentence parts: > > A loop parameter is created within each logical thread of control. > >I think that reads better and needs no comma. Perhaps, but I believe the "within each logical thread of control" is setting the stage for this whole paragraph, not just this one sentence, and so the topic of the paragraph may become less clear if you invert this introductory sentence. **************************************************************** From: Randy Brukardt Sent: Thursday, January 7, 2021 5:06 PM [Just the relevant parts of a private e-mail - Editor.] ... > > > "Upon return from Split_Into_Chunks, the actual number of chunks > > > for the loop is determined by calling the Chunk_Count operation of > > > the iterator, at which point one logical thread of control is > > > initiated for each chunk [removed comma] with an associated chunk > > > index in the range from one to the actual number of chunks. > > Without the comma this could be read as meaning "for each chunk that > has an associated chunk index" (with => that has), which I don't think > is intended. So to me the comma seems helpful. ??? That's exactly what I thought was intended. I don't see any difference between the statement with or without the comma, or for that matter, with your restatement (since every chunk has a chunk index; it doesn't make sense to have some chunks without chunk indexes). They all mean the same thing to me, so I think this is one of the most useless commas. Can you better explain the difference you are seeing (I realize that might be difficult)? ... > > > discrete_subtype_definition is present in the associated parallel > > > construct, then a chunk parameter is created [removed comma] and > > > initialized with a value from the discrete subtype defined by the > > > discrete_subtype_definition, > > I think this is OK without the comma, though I somewhat prefer the > comma. > Without the comma it could be read as "is created with a value and > initialized with a value ...", and the comma avoids that potential > reading, though it's probably clear enough what's meant and unlikely > to be interpreted that way. I don't get this, either. The comma here seems completely unnecessary: "created and initialized" seems fine as whatever it is created with before it is initialized can't have a side-effect (it's of a discrete type). I vote for getting rid of comma. And I don't see where you are thinking readers are going to conjure up an extra "with a value". ... ... > > > also consistent with the existing Ada 2012 wording [para 13/5] > > > (which is heavily modified, but not that part). I'm less annoyed > > > by the other suggestion, although I don't think subprograms "contain" > > > parameters as much as "having" parameters. > > Right. Maybe "that has" instead of "having"? (The first part of that > sentence is still a bit awkward, as it could be read as saying that > the iterator type rather than the operation has the parameter, but I > don't have a good suggestion for avoiding that.) "that has" seems a little less informal, so I think that's a good suggestion. **************************************************************** From: Gary Dismukes Sent: Thursday, January 7, 2021 5:51 PM [Just the relevant parts of a private e-mail - Editor.] ... > > > > "Upon return from Split_Into_Chunks, the actual number of chunks > > > > for the loop is determined by calling the Chunk_Count operation > > > > of the iterator, at which point one logical thread of control is > > > > initiated for each chunk [removed comma] with an associated > > > > chunk index in the range from one to the actual number of chunks. > > > > Without the comma this could be read as meaning "for each chunk that > > has an associated chunk index" (with => that has), which I don't > > think is intended. So to me the comma seems helpful. > > ??? That's exactly what I thought was intended. I don't see any > difference between the statement with or without the comma, or for > that matter, with your restatement (since every chunk has a chunk > index; it doesn't make sense to have some chunks without chunk > indexes). They all mean the same thing to me, so I think this is one of the > most useless commas. > > Can you better explain the difference you are seeing (I realize that > might be difficult)? I can try, but it's a bit subtle I admit, and maybe too subtle to matter. I agree that every chunk has a chunk index, but without the comma I can read that sentence as being something like (reversing parts of the sentence to make it clearer what I mean): for each chunk that has an associated chunk index in the range from one to the actual number of chunks, one logical thread of control is initiated. It's unlikely anyone will interpret it that way, but that's sort of how it reads to me without the comma. For me the comma helps, and makes the sentence read more naturally, but evidently for you it doesn't. ... > > > > discrete_subtype_definition is present in the associated > > > > parallel construct, then a chunk parameter is created [removed > > > > comma] and initialized with a value from the discrete subtype > > > > defined by the discrete_subtype_definition, > > > > I think this is OK without the comma, though I somewhat prefer the > > comma. > > Without the comma it could be read as "is created with a value and > > initialized with a value ...", and the comma avoids that potential > > reading, though it's probably clear enough what's meant and unlikely > > to be interpreted that way. > > I don't get this, either. The comma here seems completely unnecessary: > "created and initialized" seems fine as whatever it is created with > before it is initialized can't have a side-effect (it's of a discrete > type). I vote for getting rid of comma. And I don't see where you are > thinking readers are going to conjure up an extra "with a value". As I said, it's unlikely to be interpreted that way, and I'm fine with eliminating the comma. **************************************************************** From: Tucker Taft Sent: Thursday, January 7, 2021 6:51 PM [Just the relevant parts of a private e-mail - Editor.] > ... This paragraph is gigantic anyway, so perhaps we should think about > breaking it up. ... I would consider just splitting this into three paragraphs (yes I realize the first and last are single sentences): Upon return from Split_Into_Chunks, the actual number of chunks for the loop is determined by calling the Chunk_Count operation of the iterator, at which point one logical thread of control is initiated for each chunk, with an associated chunk index in the range from one to the actual number of chunks. Within each logical thread of control, a loop parameter is created. If a chunk_specification with a discrete_subtype_definition is present in the associated parallel construct, then a chunk parameter is created, and initialized with a value from the discrete subtype defined by the discrete_subtype_definition, so that the order of the chosen chunk parameter values correspond to the order of the chunk indices associated with the logical threads of control. The operation First of the iterator type having a Chunk parameter is called on the loop iterator, with Chunk initialized from the corresponding chunk index, to produce the initial value for the loop parameter. If the result of calling Has_Element on this initial value is False, then the execution of the logical thread of control is complete. Otherwise, the sequence_of_statements is conditionally executed and then the Next operation of the iterator type having a Chunk parameter is called, with the loop iterator, the current value of the loop parameter, and the corresponding chunk index, to produce the next value to be assigned to the loop parameter. This repeats until the result of calling Has_Element on the loop parameter is False, or the associated parallel construct is left as a consequence of a transfer of control. In the absence of a transfer of control, the associated parallel construct of a parallel generalized iterator is complete when all of its logical threads of control are complete. **************************************************************** From the AARM review of Richard Wai, October 2020 4.3.1(17.3/5): The parenthesized "box" seems unnecessary. In other places, the text simply says "<>". "use the compound delimiter <> [(box)] rather than an expression;" For an precedent in existing text, see 4.3.3-49.i/3, and new wording 49.k/4 & 4.3.5-26/5 [Editor's response: AARM notes don't provide precedent for normative rules, so the only 4.3.5(26/5) provides any precedent. Looking for other similar rules: * A similar Legality Rule is 4.3.4(11/5), and that uses "shall not use the box symbol <>". * 12.6(10) just uses "specified by a box" without using <> at all. * 12.7(4.5/3) uses "given by <>" without mentioning box at all. So it appears this is an evolving usage without much consistency. Moreover, for explanatory text like this, we try to give it exactly once per subclause, so precedent isn't necessarily obvious -- the equivalence of <> and "box" could be mentioned earlier in the clause. So I think making the text more like 4.3.4(11/5) would be better, not everyone knows that <> is called box and it doesn't hurt to reiterate it. So perhaps: "use the box compound delimiter <> rather than an expression;" end Editor's response.] ----- 4.3.3(10) Wording of the "redundant" sentence is extremely pedantic and hard to follow. Suggestion: "An applicable index constraint is a constraint that can be determined from the context of the aggregate, such as a subtype constraint or target array bounds" Or something like that.. [Editor's response: These sorts of sentences cannot be too sloppy, since they formally *are* normative wording (the "redundant" brackets are *not* normative, and since the sentence is given in a normative paragraph). I'm dubious about giving examples in this sentence given that the formal definition is directly below. The "where an array_aggregate is permitted part" seems useless and probably is what is confusing you. An array_aggregate is permitted almost everywhere! It's the others choice that isn't allowed in some contexts. And we're talking about array_aggregates; who cares about contexts where they're not allowed! The first sentence already mentioned that others choices aren't permitted in some contexts, so we don't need to repeat it. So I suggest dropping the "permitted" part, giving: An applicable index constraint is a constraint provided by certain contexts that can be used to determine the bounds of the array value specified by an array_aggregate. Since this is original Ada 95 wording, it'll go into the presentation AI. end Editor's response.] ----- 4.3.5(76/5) The example is pretty suboptimal. The conditional inside the loop is not necessary. for Item in 1 .. 5 loop Include (S, Item) Include (S, -Item) end loop; This also more closely reflects what will actually happen, and is easier to understand. [Editor's response: I'd probably write this with two loops to reflect what the aggregate actually expands into: for Item in 1 .. 5 loop Include (S, Item) end loop; for Item in 1 .. 5 loop Include (S, -Item) end loop; With this expansion, we don't need the "assuming set semantics", either, as this is what is generated. But I'm not certain whether this really reflects the point that was intended by the author. The previous example already shows the basic expansion. I'm guessing that the intent here was to show that the set would be [-5, -4, -3, -2, -1, 1, 2, 3, 4, 5], but since one can't use aggregate notation to explain how aggregate notation is interpreted (!), he ended up with this. Perhaps it would be better to write: for Item in 1 .. 5 loop Include (S, Item) end loop; for Item in -5 .. -1 loop Include (S, Item) end loop; This isn't quite as close to the expansion, but more obviously shows the result than either of the other suggestions. end Editor's response.] **************************************************************** From the AARM review of Steve Baird, October 2020 6.1.1 Paragraph 1 seems to suggest that Pre'Class and Post'Class aspects may be specified for an access-to-subprogram type. This is contradicted later. We prefer it if the RM doesn't contradict itself, although the meta-rule "if two rules in the RM contradict each other and one is more specific than the other, then the more specific rule takes precedence" does seem to apply here. Is there a problem here that needs fixing? [Editor's response: The only fix would be to delete the class-wide aspects from their current locations, move them after the current ones, and give them a new more restrictive header. Seems painful, and we don't repeat the restriction to primitives of a tagged type for the class-wide aspects, either. That is, it was always expected that the class-wide aspects would not allow everything supported by the other versions. So this seems like something that should have been done initially if it was going to be done at all. Tucker suggests replacing "an operation" with "a dispatching operation" for for Pre'Class and Post'Class. This doesn't fix the concern directly, but is thought to be an improvement. end Editor's response.] In 6.1.1(7/5), do we need to add the one word "anonymous" to clarify that the rule Similarly, a name that denotes a formal access parameter (or S'Result) of type access-to-T is interpreted as having type access-to-NT. does not apply in the case of a named access-to-T function result type? [Editor's response: I think it would be better to refer to an "access result" here to mirror the use of "access parameter", but certainly a fix is needed. So I used: Similarly, a name that denotes a formal access parameter (or S'Result{ of an access result}) of type access-to-T is interpreted as having type access-to-NT. end Editor's response.] 6.1.1(8/3) reads For an attribute_reference with attribute_designator Old, if the attribute reference has an expected type or shall resolve to a given type, the same applies to the prefix; otherwise, the prefix shall be resolved independently of context. Perhaps there is no problem here, but I'm wondering whether "shall resolve to a given type" ought to be "shall resolve to a given type or class of types" or something similar. [Editor's response: We never talk about "shall resolve to a class of types. The conditional expression wording does talk about "expected type in a class of types". It seems rare that we do that, but there is some precedent. Tucker suggested "expected type {or class of types} or shall resolve to" to fix the problem. That has an "or" problem, so I enclosed the insertion in parens: "expected type {(or class of types)} or shall resolve to" end Editor's response.] 6.5 In 5.1/5, add an "if any" modifier (surrounded by commas or parens?). The expression of an extended_return_statement is the expression (if any) of the extended_return_object_declaration of the extended_return_statement. --- In 8/4 (in the context of a return statement), we talk about "the expression". Should this be "the expression of the return statement"? I know, what other expression could it be? But still ... It doesn't help any that the possibility exists that there is no such expression and this possibility isn't addressed until after the reference to "the expression", when we get to the "unless the return object is defined by" part. This is hardly an oversight; this point was discussed (see TBH note 8.d.1/4), so perhaps nothing more needs to be done here. I think the TBH note is an acknowledgement that there is a problem and that the proposed two-word addition would help with that problem. [Editor's response: The correct definition of the term "expression of a return statement" wasn't made until now (Ada 202x, by AI12-0173-1), while the wording you are referring to was trying to avoid the badly defined term in Ada 2012. Probably the fix you suggest should be added and the TBH deleted. Part of the TBH should go after 5.1/5 as a ramification to define "expression of a return statement", which is used a lot but never formally defined. The "(if any)" suggestion seems like a good one. (I don't want to formally define "expression of a return statement", that's more likely to cause trouble than fix anything.) This is included in AI12-0418-1.] In 6.5.1(1/5), the nonnormative text "it may propagate an exception or loop forever" might be interpreted as an exhaustive list (suggesting, for example, that blocking forever awaiting the acceptance of an entry call is not a possibility). Perhaps "it may, for example, propagate ...". ****************************************************************