Version 1.4 of ai12s/ai12-0442-1.txt

Unformatted version of ai12s/ai12-0442-1.txt version 1.4
Other versions for file ai12s/ai12-0442-1.txt

!standard 3.4(34) 22-05-25 AI12-0442-1/03
!standard 3.5(58)
!standard 3.5.5(12)
!standard 3.5.9(22)
!standard 3.5.9(24)
!standard 3.6.1(12)
!standard 3.9(27)
!standard 3.9.3(16)
!standard 3.9.4(26/2)
!standard 3.9.4(33/2)
!standard 3.10.2(39)
!standard 4.3.5(85/5)
!standard 4.7(9)
!standard 4.8(15/3)
!standard 5.1(18/5)
!standard 5.2.1(8/5)
!standard 5.5(14)
!standard 6.1.1(43/3)
!standard 6.1.2(44/5)
!standard 7.3(18)
!standard 7.3(20/2)
!standard 7.3(20.1/2)
!standard 7.5(9/3)
!standard 7.6.1(24)
!standard 8.1(18)
!standard 8.5(4)
!standard 9.1(21/2)
!standard 9.2(8)
!standard 9.5.3(29)
!standard 9.6.1(90/5)
!standard 9.7.4(13)
!standard 9.8(22)
!standard 9.9(7)
!standard 9.9(8)
!standard 10.1.1(27)
!standard 10.1.4(9)
!standard 10.2(34)
!standard 11.4.2(28/2)
!standard 11.5(29)
!standard 12.5.1(5.1/4)
!standard 12.5.1(6/3)
!standard 12.5.1(24/2)
!standard 12.5.1(25)
!standard 12.5.1(26)
!standard 12.5.2(9)
!standard 12.6(11)
!standard 12.6(16.1/2)
!standard 13.4(11/5)
!standard 13.9.2(14/2)
!standard 13.11(26)
!standard 13.11.4(33/3)
!standard 13.11.4(35/3)
!standard 13.13.2(57)
!standard A.4.3(107/3)
!standard A.5.2(50)
!standard A.16(127/2)
!standard A.16(131/2)
!standard A.16.1(37/2)
!standard A.18.3(164/2)
!standard B.3.1(60)
!standard B.4(112)
!standard C.3.1(23/2)
!standard C.7.2(31)
!standard C.7.2(32)
!standard D.2.5(18/2)
!standard D.3(21)
!standard D.5.1(19)
!standard E.2.2(18)
!standard E.4.2(12)
!standard H.5(7/2)
!standard M(1/3)
!standard M.1(1/2)
!standard M.2(1/2)
!standard M.3(1/2)
!class presentation 22-04-25
!status Amendment 1-2012 22-05-05
!status ARG Approved 14-0-0 22-05-05
!status work item 22-04-25
!status received 22-02-18
!priority Critical
!difficulty Medium
!subject Rewordings of notes
!summary
Many notes need to be reworded.
!question
ISO comment #16 includes a mention of the fact that the drafting rules do not allow any requirements, recommendations, or permissions in notes. We of course follow the spirit of that rule, but we do not follow the letter, which does not allow any phrasing that might be mistook for one of these things.
We also need to reword many notes to avoid words and phrases that aren't allowed at all ("must", "might", "could", "need") - see AI12-0445-1.
There are many notes that need rewording, and for many of them the rewordings are complex.
!recommendation
Simple rewordings which simply replace an existing word with "can" are found in AI12-0440-1. This AI contains the more complex rewordings necessary for the remaining notes.
!wording
Modify 3.4(34):
NOTE 7 For an inherited subprogram, the subtype of a formal parameter of the derived type {can be such that it has no}[need not have any] value in common with the first subtype of the derived type.
[Replace "need not" -Editor.]
Modify 3.5(58):
NOTE 2 For a subtype of a scalar type, the result delivered by the attributes Succ, Pred, and Value {can be outside}[might not belong to] the subtype; similarly, the actual parameters of the attributes Succ, Pred, and Image {can also be outside}[need not belong to] the subtype.
["Might not" and "need not" are both on the ISO list (as opposed to the Directives). AI12-0445-1 now defines "outside" for this use (it already appeared in a pair of Implementation Permissions) - Editor.]
Modify 3.5.5(12):
NOTE 4 For a subtype of a discrete type, the result delivered by the attribute Val {can be outside}[might not belong to] the subtype; similarly, the actual parameter of the attribute Pos {can also be outside}[need not belong to] the subtype. The following relations are satisfied (in the absence of an exception) by these attributes:
["Might not" and "need not" are both on the ISO list; see 3.5 above - Editor.]
Modify 3.5.9(22):
NOTE The {specified bounds themselves can be outside the} base range of an ordinary fixed point type [need not include the specified bounds themselves] so that the range specification can be given in a natural way, such as:
["Might not" and "need not" are both on the ISO list; see 3.5 above - Editor.]
Modify 3.5.9(24):
With 2's complement hardware, such a type {would typically}[could] have a signed 16-bit representation, using 1 bit for the sign and 15 bits for fraction, resulting in a base range of -1.0 .. 1.0-2.0**(-15).
[Replace "could" - Editor.]
Modify 3.6.1(12):
Board : Matrix(1 .. 8, 1 .. 8); -- see 3.6 Rectangle : Matrix(1 .. 20, 1 .. 30); Inverse : Matrix(1 .. N, 1 .. N); -- N {can be nonstatic}[need not be static]
["need not" is replaced - Editor.]
Modify 3.9(27):
NOTE 1 A type declared with the reserved word tagged {is}[should] normally [be] declared in a package_specification, so that new primitive subprograms can be declared for it.
[Replace "should". This is a usage recommendation, and could have been moved unchanged to a new normative "Usage Advice" grouping - Editor.]
Modify 3.9.3(16):
NOTE 3 Notes on the example: Given the above abstract type, one {can}[could then] derive various (nonabstract) extensions of the type, representing alternative implementations of a set. One {possibility is to}[might] use a bit vector, but impose an upper bound on the largest element representable, while another {possible implementation is}[might use] a hash table, trading off space for flexibility.
[Replace "might" (twice) and "could" - Editor.]
Modify 3.9.4(26/2):
This defines a Queue interface defining a queue of people. (A similar design {is possible}[could be created] to define any kind of queue simply by replacing Person_Name by an appropriate type.) The Queue interface has four dispatching operations, Append, Remove_First, Cur_Count, and Max_Count. The body of a class-wide operation, Transfer is also shown. Every nonabstract extension of Queue {will}[must] provide implementations for at least its four dispatching operations, as they are abstract. Any object of a type derived from Queue {can}[may] be passed to Transfer as either the From or the To operand. The two operands {can be of different types in a}[need not be of the same type in any] given call.
[Replacement for "May, "need not", "must", "could be" - this paragraph has everything we're not supposed to say! - Editor.]
Modify 3.9.4(33/2):
An interface such as Queue can be used directly as the parent of a new type (as shown here), or can be used as a progenitor when a type is derived. In either case, the primitive operations of the interface are inherited. For Queue, the implementation of the four inherited routines {will necessarily}[must] be provided. Inside the call of Transfer, calls will dispatch to the implementations of Append and Remove_First for type Fast_Food_Queue.
Modify 3.10.2(39):
NOTE 7 An implementation {can}[may] consider two access-to-subprogram values to be unequal, even though they designate the same subprogram. {For instance, this can happen}[This might be] because one points directly to the subprogram, while the other points to a special prologue that performs an Elaboration_Check and then jumps to the subprogram. See 4.5.2.
[Replace "may" and "might".]
Modify 4.3.5(85/5):
-- A map aggregate where the values produced by the -- iterated_element_association are of the same type as the key -- ({hence}[eliminating the need for] a separate key_expression {is unnecessary}): M := [for Key of Keys => Integer'Image (Key)];
[Replace "need". I tried "required", but it implies a requirement and thus can't be used - Editor.]
Modify 4.7(9):
Part of the examples:
for J in Code'(Fix) .. Code'(Dec) loop ... -- qualification {is necessary}[needed] for either Fix or Dec for J in Code range Fix .. Dec loop ... -- qualification unnecessary for J in Code'(Fix) .. Dec loop ... -- qualification unnecessary for Dec
[Replace "needed" - Editor.]
Modify 4.8(15/3):
NOTE 4 Implementations {can, if desired}[are permitted, but not required], [to] provide garbage collection.
[Neither a permission nor a requirement should be mentioned here, just a statement of fact - Editor.]
Modify 5.1(18/5):
During the execution of a parallel construct, it is a bounded error to invoke an operation that is potentially blocking (see 9.5). Program_Error is raised if the error is detected by the implementation; otherwise, the execution of the potentially blocking operation {can either}[might] proceed normally, or it {can}[might] result in the indefinite blocking of some or all of the logical threads of control making up the current task.
[Replace "might" - Editor.]
Modify 5.2.1(8/5):
My_Complex_Array : array (1 .. Max) of Complex; -- See 3.3.2, 3.8. ... -- Square the element in the Count (see 3.3.1) position: My_Complex_Array (Count) := (Re => @.Re**2 - @.Im**2, Im => 2.0 * @.Re * @.Im); -- A target_name can be used multiple times and as a prefix if {desired}[needed].
[Replace "needed" - Editor.]
Modify 5.5(14):
NOTE 2 {No separate}[An] object_declaration {is expected}[should not be given] for a loop parameter, since the loop parameter is automatically declared by the loop_parameter_specification. The scope of a loop parameter extends from the loop_parameter_specification to the end of the loop_statement, and the visibility rules are such that a loop parameter is only visible within the sequence_of_statements of the loop.
[I tried "ought not", but that is considered a synomym for "shall not". This really reads as a recommendation, which is not allowed in a note. We use notes for recommendations to the programmer, but that is simply not allowed (and probably would be considered inappropriate for a Standard at all) - Editor.]
Modify 6.1.1(43/3):
NOTE 1 A precondition is checked just before the call. If another task can change any value that the precondition expression depends on, the precondition {can evaluate to False}[need not hold] within the subprogram or entry body.
["need not" is replaced - Editor.]
Modify 6.1.2(44/5):
NOTE For an example of the use of these aspects[ and attributes], see the Vector container definition in A.18.2.
Modify 7.3(18):
NOTE 1 The partial view of a type as declared by a private_type_declaration is defined to be a composite view (in 3.2). The full view of the type {can}[might or might not] be {elementary or }composite. A private extension is also composite, as is its full view.
["might or might not" is replaced by giving both possibilities - Editor.]
Modify 7.3(20/2):
NOTE 3 The ancestor type specified in a private_extension_declaration and the parent type specified in the corresponding declaration of a record extension given in the private part {can be different}[need not be the same]. If the ancestor type is not an interface type, the parent type of the full view can be any descendant of the ancestor type. In this case, for a primitive subprogram that is inherited from the ancestor type and not overridden, the formal parameter names and default expressions (if any) come from the corresponding primitive subprogram of the specified ancestor type, while the body comes from the corresponding primitive subprogram of the parent type of the full view. See 3.9.2.
["need not" is replaced - Editor.]
Modify 7.3(20.1/2):
NOTE 4 If the ancestor type specified in a private_extension_declaration is an interface type, the parent type can be any type so long as the full view is a descendant of the ancestor type. The progenitor types specified in a private_extension_declaration and the progenitor types specified in the corresponding declaration of a record extension given in the private part {are not necessarily}[need not be] the same - {it is only necessary}[the only requirement is] that the private extension and the record extension be descended from the same set of interfaces.
["need not" and "requirement" are replaced - Editor.]
Modify 7.5(9/3):
NOTE 1 While it is allowed to write initializations of limited objects, such initializations never copy a limited object. The source of such an assignment operation {will}[must] be an aggregate or function_call, and such aggregates and function_calls {will}[must] be built directly in the target object (see 7.6).
[Replace "must" - Editor.]
Modify 7.6.1(24):
NOTE 4 The Finalize procedure is called upon finalization of a controlled object, even if Finalize was called earlier, either explicitly or as part of an assignment; hence, if a controlled type is visibly controlled (implying that its Finalize primitive is directly callable), or is nonlimited (implying that assignment is allowed), its Finalize procedure {is ideally}[should be] designed to have no ill effect if it is applied a second time to the same object.
[Another usage recommendation (see 3.9 note) - Editor.]
Modify 8.1(18):
NOTE 3 For a declarative region that comes in multiple parts, the text of the declarative region does not {include}[contain] any {of the} text that {appears}[might appear] between the parts. Thus, when a portion of a declarative region is said to extend from one place to another in the declarative region, the portion does not contain any {of the} text that {appears}[might appear] between the parts of the declarative region.
[Replace "might"; "can" does not work here, so a more significant rewrite - Editor.]
Modify 8.5(4):
NOTE 1 Renaming {can}[may] be used to resolve name conflicts and to act as a shorthand. Renaming with a different identifier or operator_symbol does not hide the old name; the new name and the old name {can}[need not] be
visible at {different}[the same] places.
[Replace "may" and "need not" - Editor.]
Modify 9.1(21/2):
NOTE 3 A task type is a limited type (see 7.5), and hence precludes use of assignment_statements and predefined equality operators. If {a programmer wants to write }an application {that stores and exchanges}[needs to store and exchange] task identities, {they}[it] can do so by defining an access type designating the corresponding task objects and by using access values for identification purposes. Assignment is available for such an access type as for any access type. Alternatively, if the implementation supports the Systems Programming Annex, the Identity attribute can be used for task identification (see C.7.1).
["needs" is replaced (in the phrase "needs to", which is definitely on the ISO blacklist) - Editor.]
Modify 9.2(8):
NOTE 2 If several tasks are activated together, the execution of any of these tasks {can proceed without waiting until}[need not await] the end of the activation of the other tasks.
["need not" is replaced - Editor.]
Modify 9.5.3(29):
NOTE 4 The condition of an entry_barrier is allowed to be evaluated by an implementation more often than strictly necessary, even if the evaluation {can}[might] have side effects. On the other hand, an implementation {can avoid reevaluating}[need not reevaluate] the condition if nothing it references was updated by an intervening protected action on the protected object, even if the condition references some global variable that {is}[might have been] updated by an action performed from outside of a protected action.
[Replace "might" and "need not". The second "might" does not work with "can", so a different rewording is needed - Editor.]
Modify 9.6.1(90/5):
NOTE 1 The implementation-defined time zone of package Calendar {can}[may, but need not,] be the local time zone{, or it can be some other time zone like UTC}. Local_Time_Offset always returns the difference relative to the implementation-defined time zone of package Calendar. If Local_Time_Offset does not raise Unknown_Zone_Error, UTC time can be safely calculated (within the accuracy of the underlying time-base).
[Replace "may", eliminate "need not" - Editor.]
Modify 9.7.4(13):
select delay 5.0; Put_Line("Calculation does not converge"); then abort -- This calculation {is expected to}[should] finish in 5.0 seconds; -- if not, it is assumed to diverge. Horribly_Complicated_Recursive_Function(X, Y); end select;
["Should" not allowed in examples (I checked the Directives) - Editor.]
Modify 9.8(22):
NOTE 1 An abort_statement {is best}[should be] used only in situations requiring unconditional termination.
[Another usage recommendation (see 3.9 note) - Editor.]
Modify 9.9(7):
NOTE 2 Within task units, {by}[algorithms] interrogating the attribute E'Count {an algorithm can}[should take precautions to] allow for the increase of the value of this attribute for incoming entry calls, and its decrease, for example with timed_entry_calls. {A}[Also, a] conditional_entry_call {can also}[may] briefly increase this value, even if the conditional call is not accepted.
[Another usage recommendation (see 3.9 note) - Editor.]
Modify 9.9(8):
NOTE 3 Within protected units, {by}[algorithms] interrogating the attribute E'Count in the entry_barrier for the entry E {an algorithm can}[should take precautions to] allow for the evaluation of the condition of the barrier both before and after queuing a given caller.
[Another usage recommendation (see 3.9 note) - Editor.]
Modify 10.1.1(27):
NOTE 1 A simple program {can}[may] consist of a single compilation unit. A compilation {can have no}[need not have any] compilation units; for example, its text can consist of pragmas.
[Replace "may" and "need not" - Editor.]
Modify 10.1.4(9):
NOTE 2 An implementation {can}[may] support a concept of a library, which contains library_items. If multiple libraries are supported, the implementation {can document}[has to define] how a single environment is constructed when a compilation unit is submitted to the compiler. Naming conflicts between different libraries {can, for example,}[might] be resolved by treating each library as the root of a hierarchy of child library units.
[Eliminates "has to define", which sounds like a requirement, as well as the usual "may" and "might" fixes - Editor.]
Modify 10.2(34):
NOTE 4 A partition (active or otherwise) {does not necessarily}[need not] have a main subprogram. In such a case, all the work done by the partition would be done by elaboration of various library_items, and by tasks created by that elaboration. Passive partitions, which cannot have main subprograms, are defined in Annex E, "Distributed Systems".
["Need not" is replaced - Editor.]
Modify 11.4.2(28/2):
NOTE Normally, the boolean expression in a pragma Assert {does}[should] not call functions that have significant side effects when the result of the expression is True, so that the particular assertion policy in effect will not affect normal operation of the program.
[Another usage recommendation (see 3.9 note) - Editor.]
Modify 11.5(29):
NOTE 1 There is no guarantee that a suppressed check is actually removed; hence a pragma Suppress {is useful only to improve efficiency}[should be used only for efficiency reasons].
[Remove recommendation - Editor.]
Modify 12.5.1(5.1/4):
The actual type for a formal derived type shall be a descendant of the ancestor type and every progenitor of the formal type. [If the formal type is nonlimited, the actual type shall be nonlimited. ]The actual type for a formal derived type shall be tagged if and only if the formal derived type is a private extension. If the reserved word synchronized appears in the declaration of the formal derived type, the actual type shall be a synchronized tagged type.
[See discussion after 12.5.1(26) for why we're making this change - Editor.]
Modify 12.5.1(6/3):
If a formal private or derived subtype is definite, then the actual subtype shall also be definite. {If the formal type is nonlimited, the actual type shall be nonlimited.}
[See discussion after 12.5.1(26) for why we're making this change - Editor.]
Delete 12.5.1(24/2 - 26):
NOTE 1 In accordance with the general rule that the actual type shall belong to the category determined for the formal (see 12.5, "Formal Types"):
* If the formal type is nonlimited, then so shall be the actual;
* For a formal derived type, the actual shall be in the class rooted at the ancestor subtype.
[As a note, this should not include "shall".
Tucker says this isn't a Note; it should be Redundant text. However, we have such redundant text at the top of the subclause (not as formally described, but definitely the same point). It appears this Note predates the formal use of "category" and the associated rewrite of the introduction to this subclause (the original Ada 95 wording used "class"). The AARM proof also gives the reference to 12.5.
Additionally, we have a rule that the actual is a descendant of the ancestor (it's marked as redundant, and the proof given is similar to the note above), so the second bullet is explicitly stated and doesn't follow from anything. Finally, 12.5.1(5.1/4), sentence 2 explicitly states that the actual has to be nonlimited if the formal is (and this is not even marked as Redundant).
Unfortunately, it is unclear if that sentence applies to formal private types; read literally, it does, but it is in a paragraph that otherwise only talks about formal derived types. We therefore move it to 12.5.1(6/3) to make it clear that it applies to both. If we were working on a new revision rather than "minor" changes to an approved DIS, I would suggest moving the entirety of 12.5.1(6) (with the new part) after 12.5.1(4) so that the rules that apply to all private and derived formals appear before the ones that apply only to derived formals. But that seems like a bit much as an editorial change. One could also consider moving the "limited" sentence to 12.5, since it appears to be written to apply to all formal types, but that is definitely out of bounds at this time.)
Ultimately, there seems to be nothing in this note that isn't already stated elsewhere (several times), and thus there is no reason to keep any of it, even in the AARM (especially given that it is problematic). It is deleted - Editor.]
Delete 12.5.2(9):
NOTE The actual type shall be in the class of types implied by the syntactic category of the formal type definition (see 12.5, " Formal Types"). For example, the actual for a formal_modular_type_definition shall be a modular type.
[As a note, this should not include "shall". Tucker says this isn't a Note; it should be Redundant text. However, we have such redundant text at the top of the subclause (not quite as formally stated, but definitely the same point). Moreover, the AARM proof essentially repeats this note. As such, this note is completely redundant and should simply be deleted - Editor.]
Modify 12.5.5(5/5):
Example of the use of a generic with a formal interface type, to establish a standard interface that all tasks {will}[need to] implement so they can be managed appropriately by an application-specific scheduler:
["need to" is replaced - Editor.]
Modify 12.6(11):
NOTE 1 The matching rules for formal subprograms state requirements that are similar to those applying to subprogram_renaming_declarations (see 8.5.4). In particular, the name of a parameter of the formal subprogram {can be different from}[need not be the same as] that of the corresponding parameter of the actual subprogram; similarly, for these parameters, default_expressions need not correspond.
["need not" is replaced - Editor.]
Modify 12.6(16.1/2):
NOTE 7 The subprogram declared by a formal_abstract_subprogram_- declaration is an abstract subprogram. All calls on a subprogram declared by a formal_abstract_subprogram_declaration {are limited to}[must be] dispatching calls. See 3.9.3.
[Replace "must" - Editor.]
Modify 13.4(11/5):
NOTE Attribute Enum_Rep {can}[may] be used to query the internal codes used for an enumeration type; attribute Enum_Val {can}[may] be used to convert from an internal code to an enumeration value. The other attributes of the type, such as Succ, Pred, and Pos, are unaffected by {an}[the] enumeration_representation_clause. For example, Pos always returns the position number, not {an}[the] internal integer code that {was}[might have been] specified in an enumeration_representation_clause.
[Fix "may", "might have been". Tuck suggested using "an" rather than "the" to avoid implying that an enumeration_representation_clause always exists - Editor.]
Modify 13.9.2(14/2):
NOTE 3 The Valid attribute {can}[may] be used to check the result of calling an instance of Unchecked_Conversion (or any other operation that can return invalid values). However, an exception handler {is still useful}[should also be provided] because implementations are permitted to raise Constraint_Error or Program_Error if they detect the use of an invalid representation (see 13.9.1).
[Replace "may", usage recommendation (see 3.9 note) - Editor.]
Modify 13.11(26):
NOTE 1 A user-defined storage pool type can be obtained by extending the Root_Storage_Pool type, and overriding the primitive subprograms Allocate, Deallocate, and Storage_Size. A user-defined storage pool can then be obtained by declaring an object of the type extension. The user can override Initialize and Finalize if there is any {desire}[need] for nontrivial initialization and finalization for a user-defined pool type. For example, Finalize {can}[might] reclaim blocks of storage that are allocated separately from the pool object itself.
[Replace "might" and "need" - Editor.]
Modify 13.11.4(33/3):
NOTE 1 A user-defined storage pool type that supports subpools can be implemented by extending the Root_Storage_Pool_With_Subpools type, and overriding the primitive subprograms Create_Subpool, Allocate_From_Subpool, and Deallocate_Subpool. Create_Subpool {is expected to}[should] call Set_Pool_Of_Subpool before returning the subpool handle. To make use of such a pool, a user {can}[would] declare an object of the type extension, use it to define the Storage_Pool attribute of one or more access types, and then call Create_Subpool to obtain subpool handles associated with the pool.
[Replace "should", "would" - Editor.]
Modify 13.11.4(35/3):
NOTE 3 The pool implementor {can}[should] override Default_Subpool_For_Pool if {they want} the pool [is] to support a default subpool for the pool. The implementor can override Deallocate if individual object reclamation is to be supported, and can override Storage_Size if there is some limit on the total size of the storage pool. The implementor can override Initialize and Finalize if there is any {desire}[need] for nontrivial initialization and finalization for the pool as a whole. For example, Finalize {can}[might] reclaim blocks of storage that are allocated over and above the space occupied by the pool object itself. The pool implementor {can}[may] extend the Root_Subpool type as necessary to carry additional information with each subpool provided by Create_Subpool.
[Replace "may", "might", "need", and "should". The grand slam - Editor.]
Modify 13.13.2(57):
NOTE 1 For a definite subtype S of a type T, only T'Write and T'Read are {necessary}[needed] to pass an arbitrary value of the subtype through a stream. For an indefinite subtype S of a type T, T'Output and T'Input will normally be {necessary}[needed], since T'Write and T'Read do not pass bounds, discriminants, or tags.
["needed" is replaced - Editor.]
Modify A.4.3(107/3):
NOTE 1 In the Index and Count functions taking Pattern and Mapping parameters, {for there to be a match, }the actual String parameter passed to Pattern {can contain only}[should comprise] characters occurring as target characters of the mapping. [Otherwise, the pattern will not match.]
[Rewrite to eliminate "should" - Editor.]
Modify A.5.2(50):
NOTE 3 A given implementation of the Random function in Numerics.Float_Random {is not guaranteed to}[may or may not] be capable of delivering the values 0.0 or 1.0. {Applications will be more portable if they}[Portable applications should] assume that these values, or values sufficiently close to them to behave indistinguishably from them, can occur. If a sequence of random integers from some [fixed ]range is {necessary}[needed], {it is preferred that }the application [should use]{uses one of} the Random function{s} in an appropriate instantiation of Numerics.Discrete_Random, rather than transforming the result of the Random function in Numerics.Float_Random.[ However, some applications with unusual requirements, such as for a sequence of random integers each drawn from a different range, will find it more convenient to transform the result of the floating point Random function. For M >= 1, the expression]
[Replace "may or may not", "should", "need". This includes a usage recommendation, see the note at 3.9. See below for why we're deleting the "however" part. - Editor.]
Delete A.5.2(51).
Modify A.5.2(52):
{AARM Reason: One might think that a simple transformation of the result of the floating point Random function such as Integer(Float(M) * Random(G)) mod M) would give a uniform distribution. But this is only true if the period of the underlying generator is a multiple of M. (This usually requires that M be a power of two.) In other cases, the mod operation maps slightly more random values to a some result values than others. It is easy to see this: consider a 4-bit random integer (with a range of 0 .. 15). If one mods this by 6 to get a value in 0 .. 5 (to which one would add 1 to get the value of a die roll), 3 values would be mapped to each value 0 .. 3, but only 2 values would be mapped to 4 and 5. Even when the input is uniformly distributed, the output clearly is not. A similar effect occurs regardless of the number of bits in the random integer. Since it takes care to get this right, users should use the provided functions (which presumably do this correctly - AI12-0144-1 contains a correct algorithm) and resist the urge to "roll-their-own".}
{NOTE 4: }[transforms the result of Random(G) to an integer uniformly distributed over the range 0 .. M–1; it is valid even if Random delivers 0.0 or 1.0. Each value of the result range is possible, provided that M is not too large. ]Exponentially distributed (floating point) random numbers with mean and standard deviation 1.0 can be obtained by the transformation
[We delete the text about tranforming the result of the float random to get uniformly distributed integers. There are two problems with this:
* First, since AI12-0144-1 added a dedicated routine to handle the supposed "unusual requirement" as described here, it doesn't make sense to explain a different way to do that operation.
* Second, the given transformation does not provide a uniformly distributed result unless M is a power of two (on a 2's complement machine). The result is close to uniformly distributed, but the difference can matter if enough random values are generated. (The new AARM note attempts to explain why.) The newly provided function presumably does give a true uniform distribution (assuming the underlying generator does) - AI12-0144-1 gives a correct algorithm used in an open source SSH implementation - so it is way better to use that.
- Editor.]
Modify A.16(127/2):
NOTE 1 The operations Containing_Directory, Full_Name, Simple_Name, Base_Name, Extension, and Compose operate on file names, not external files. The files identified by these operations do not {necessarily}[need to] exist. Name_Error is raised only if the file name is malformed and cannot possibly identify a file. Of these operations, only the result of Full_Name depends on the current default directory; the result of the others depends only on their parameters.
["need" is replaced - Editor.]
Modify A.16(131/2):
NOTE 5 To move a file or directory to a different location, use Rename. Most target systems will allow renaming of files from one directory to another. If the target file or directory {can}[might] already exist, {delete} it [should be deleted] first.
[Replace "might" and "should" - Editor.]
Modify A.16.1(37/2):
NOTE 1 These operations operate on file names, not external files. The files identified by these operations do not {necessarily}[need to] exist. Name_Error is raised only as specified or if the file name is malformed and cannot possibly identify a file. The result of these operations depends only on their parameters.
["need" is replaced - Editor.]
Modify A.18.3(164/2):
NOTE Sorting a list never copies elements, and is a stable sort (equal elements remain in the original order). This is different than sorting an array or vector, which {will often}[may need to] copy elements, and {hence} is probably not a stable sort.
[Replace "May need" - Editor.]
Modify B.3.1(60):
* the allocated object {can}[should] be freed by the programmer via a call of Free, {rather than by calling a}[not by a called] C function.
[Reword to eliminate "should". The rest of Note 1 is modified in AI12-0440-1.]
Modify part of B.4(112):
-- Assume that a COBOL program has created a sequential file with -- the following record structure, and that we {want}[need] to -- process the records in an Ada program
Modify C.3.1(23/2):
NOTE 2 {For a}[A] protected object that has a (protected) procedure attached to an interrupt{, the correct}[ should have a] ceiling priority {is }at least as high as the highest processor priority at which that interrupt will ever be delivered.
[Reword to eliminate "should", usage recommendation (see 3.9 note) - Editor.]
Modify C.7.2(31):
NOTE 1 An attribute always exists (after instantiation), and has the initial value. {An implementation can avoid using}[It need not occupy] memory {to store the attribute value} until the first operation that [potentially] changes the attribute value. The same holds true after Reinitialize.
[Rewrite to replace "need not" - Editor.]
Modify C.7.2(32):
NOTE 2 The result of the Reference function [should be used with care; it] is always safe to use [that result] in the task body whose attribute is being accessed. However, when the result is being used by another task, the programmer {will want to}[must] make sure that the task whose attribute is being accessed is not yet terminated. Failing to do so {can}[could] make the program execution erroneous.
[Rewrite to eliminate multiple banned phrases - Editor.]
Modify D.2.1(12):
NOTE 2 An example of a possible implementation-defined execution resource is a page of physical memory, which {must}[needs to] be loaded with a particular page of virtual memory before a task can continue execution.
[Replace "needs". This is a proper use of "must" to represent an external constraint (in this case, by the hardware). At least I hope so - Editor.]
Modify D.2.5(18/2):
NOTE 1 Due to implementation constraints, the quantum value returned by Actual_Quantum {can differ from}[might not be identical to] that set with Set_Quantum.
[Getting rid of the "not" helps us use "can" here - Editor.]
Modify D.3(21):
NOTE 4 When specifying the ceiling of a protected object, [one should choose] a {correct }value {is one }that is at least as high as the highest active priority at which tasks can be executing when they call protected operations of that object. In determining this value the following factors, which can affect active priority, {are relevant}[should be considered]: the effect of Set_Priority, nested protected operations, entry calls, task activation, and other implementation-defined factors.
[Reword to eliminate "should" - Editor.]
Modify D.5.1(19):
NOTE 5 Changing the priorities of a set of tasks can be performed by a series of calls to Set_Priority for each task separately. {This can be done}[For this to work] reliably[, it should be done] within a protected operation that has high enough ceiling priority to guarantee that the operation completes without being preempted by any of the affected tasks.
[Reword to eliminate "should" - Editor.]
Modify E.2.2(18):
NOTE 1 A remote types library unit {is not necessarily}[need not be] pure, and the types it defines {can}[may] include levels of indirection implemented by using access types. User-specified Read and Write attributes (see 13.13.2) provide for sending values of such a type between active partitions, with Write marshalling the representation, and Read unmarshalling any levels of indirection.
[Replace "may", "need not" - Editor.]
Modify E.4.2(12):
* The Tape_Client procedure references only declarations in the Tapes and Name_Server packages. Before using a tape for the first time, it {will}[needs to] query the Name_Server for a system-wide identity for that tape. From then on, it can use that identity to access the tape device.
[Replace "needs" - Editor.]
Modify H.5(7/2):
NOTE An operation that causes a task to be blocked within a foreign language domain is not defined to be potentially blocking, and {is unlikely to}[need not] be detected.
[Replace "need not" - Editor.]
Modify M(1/3):
The Ada language allows for certain target machine dependences in a controlled manner. Each Ada implementation {is required to}[must] document many characteristics and properties of the target system. This Reference Manual contains specific documentation requirements. In addition, many characteristics that require documentation are identified throughout this Reference Manual as being implementation defined. Finally, this Reference Manual requires documentation of whether implementation advice is followed. The following subclauses provide summaries of these documentation requirements.
Modify M.1(1/2):
In addition to implementation-defined characteristics, each Ada implementation {is required to}[must] document various properties of the implementation:
Modify M.2(1/2):
The Ada language allows for certain machine dependences in a controlled manner. Each Ada implementation {is required to}[must] document all implementation-defined characteristics:
Modify M.3(1/2):
This Reference Manual sometimes gives advice about handling certain target machine dependences. Each Ada implementation {is required to}[must] document whether that advice is followed:
[The !appendix has several further occurrences of the unallowed words that we are not proposing to change at this time, and why we think no change is needed - Editor.]
!discussion
To summarize the ISO rules from the Directives part 2 (often referred to as the drafting standard):
Requirements use "shall" preferably, or phrases involving forms of "require", "has to", or "it is necessary". "Must" is not allowed (it can be used for external requirements, such as government laws, but that usually doesn't apply to us).
Recommendations use "should" preferably, or phrases involving forms of "recommend" or "ought to".
Permissions should use "may" preferably, or phrases using forms of permit or allow. "Might" is not allowed in this context. Negative forms are not allowed (no "may not"); permissions must be positive. A quote: "Rather than using negative permissions, either rewrite the sentence to state what is permitted, or rewrite as a requirement/recommendation not to do something."
Possibility should use "can", or phrases using forms of "able" or "possible".
ISO has taken this further and does not want to see "might", "could", or "need" at all; they assume that they are being used in one of the above contexts. Since that is not a rule but rather a recommendation, we can be selective in applying it to non-normative things like notes.
Note that while some phrases are given meanings, other uses of the words seem to be allowed by the Directives. For instance, "necessary" is used in many contexts in the Directives that are not requirements.
The editor checked the Directives and examples have the same limitations on wording as notes, so examples have been included here.
---
The editor has created a file that contains just the non-normative notes and examples. In this file, we have the following number of occurrences:
shall 5 may 64 should 25
permit 10 (including two "permissible") require 58 recommend 8 ought 0 possible 17 -- This is OK in notes.
must 7 might 27 could 10 need 41
----
The first 3 words were explicitly mentioned in the comments, so they HAVE to be eliminated. The remaining words probably should be eliminated if possible.
There are nearly 100 paragraphs here that we have to fix, and another hundred that should be looked at. There is not a one-size-fits all solution. Many of the occurrences of "may" and "might" could be replaced by "can", but certainly not all. (Those "easy" cases are found in AI12-0440-1.)
---
We have several options for dealing with these notes.
First, since these are notes and examples, we have the option of eliminating them completely, either from the ISO version only, or from both versions (in which case the note probably would be moved to the AARM). But we ought to do that only in cases where a rewording is not valuable for one reason or another.
Second, we could consider making wording changes only for the ISO version (new commands would be needed in the formatter to support that if is done a lot
- currently, we can only do that on a full paragraph basis or with a few
macros - but new commands should not be hard to define and implement). However, that would add complications to future maintenance (as we would need to somehow have both versions in any Corrigendum document, one for our use and one for the actual ISO Corrigendum).
Therefore, simply changing the text of the RM (and therefore of the ISO standard) is preferred so long as we have a rewording that does not clearly alter the meaning or harm the understandability of the text.
!comment Only a few changes are defined with Corrigendum sections.
!corrigendum 3.5.5(12)
Replace the paragraph:
NOTE 4   For a subtype of a discrete type, the result delivered by the attribute Val might not belong to the subtype; similarly, the actual parameter of the attribute Pos need not belong to the subtype. The following relations are satisfied (in the absence of an exception) by these attributes:
by:
NOTE 4   For a subtype of a discrete type, the result delivered by the attribute Val can be outside the subtype; similarly, the actual parameter of the attribute Pos can also be outside the subtype. The following relations are satisfied (in the absence of an exception) by these attributes:
!corrigendum 3.5.9(22)
Replace the paragraph:
NOTE   The base range of an ordinary fixed point type need not include the specified bounds themselves so that the range specification can be given in a natural way, such as:
by:
NOTE   The specified bounds themselves can be outside the base range of an ordinary fixed point type so that the range specification can be given in a natural way, such as:
!corrigendum 3.5.9(24)
Replace the paragraph:
With 2's complement hardware, such a type could have a signed 16-bit representation, using 1 bit for the sign and 15 bits for fraction, resulting in a base range of -1.0 .. 1.0-2.0**(-15).
by:
With 2's complement hardware, such a type would typically have a signed 16-bit representation, using 1 bit for the sign and 15 bits for fraction, resulting in a base range of -1.0 .. 1.0-2.0**(-15).
!corrigendum 3.9.4(26/2)
Replace the paragraph:
This defines a Queue interface defining a queue of people. (A similar design could be created to define any kind of queue simply by replacing Person_Name by an appropriate type.) The Queue interface has four dispatching operations, Append, Remove_First, Cur_Count, and Max_Count. The body of a class-wide operation, Transfer is also shown. Every non-abstract extension of Queue must provide implementations for at least its four dispatching operations, as they are abstract. Any object of a type derived from Queue may be passed to Transfer as either the From or the To operand. The two operands need not be of the same type in any given call.
by:
This defines a Queue interface defining a queue of people. (A similar design is possible to define any kind of queue simply by replacing Person_Name by an appropriate type.) The Queue interface has four dispatching operations, Append, Remove_First, Cur_Count, and Max_Count. The body of a class-wide operation, Transfer is also shown. Every nonabstract extension of Queue will provide implementations for at least its four dispatching operations, as they are abstract. Any object of a type derived from Queue can be passed to Transfer as either the From or the To operand. The two operands can be of different types in a given call.
!corrigendum 3.9.4(33/2)
Replace the paragraph:
An interface such as Queue can be used directly as the parent of a new type (as shown here), or can be used as a progenitor when a type is derived. In either case, the primitive operations of the interface are inherited. For Queue, the implementation of the four inherited routines must be provided. Inside the call of Transfer, calls will dispatch to the implementations of Append and Remove_First for type Fast_Food_Queue.
by:
An interface such as Queue can be used directly as the parent of a new type (as shown here), or can be used as a progenitor when a type is derived. In either case, the primitive operations of the interface are inherited. For Queue, the implementation of the four inherited routines will be required to be provided. Inside the call of Transfer, calls will dispatch to the implementations of Append and Remove_First for type Fast_Food_Queue.
!corrigendum 4.3.5(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 5.1(15)
Insert after the paragraph:
The execution of a sequence_of_statements consists of the execution of the individual statements in succession until the sequence_ is completed.
the new paragraphs:
Within a parallel construct, if a transfer of control out of the construct is initiated by one of the logical threads of control, an attempt is made to cancel all other logical threads of control initiated by the parallel construct. Once all other logical threads of control of the construct either complete or are canceled, the transfer of control occurs. If two or more logical threads of control of the same construct initiate such a transfer of control concurrently, one of them is chosen arbitrarily and the others are canceled.
When a logical thread of control is canceled, the cancellation causes it to complete as though it had performed a transfer of control to the point where it would have finished its execution. Such a cancellation is deferred while the logical thread of control is executing within an abort-deferred operation (see 9.8), and may be deferred further, but not past a point where the logical thread initiates a new nested parallel construct or reaches an exception handler that is outside such an abort-deferred operation.
Bounded (Run-Time) Errors
During the execution of a parallel construct, it is a bounded error to invoke an operation that is potentially blocking (see 9.5). Program_Error is raised if the error is detected by the implementation; otherwise, the execution of the potentially blocking operation can either proceed normally, or it can result in the indefinite blocking of some or all of the logical threads of control making up the current task.
!corrigendum 5.2.1(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 6.1.2(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum 9.1(21/2)
Replace the paragraph:
NOTE 3   A task type is a limited type (see 7.5), and hence precludes use of assignment_statements and predefined equality operators. If an application needs to store and exchange task identities, it can do so by defining an access type designating the corresponding task objects and by using access values for identification purposes. Assignment is available for such an access type as for any access type. Alternatively, if the implementation supports the Systems Programming Annex, the Identity attribute can be used for task identification (see C.7.1).
by:
NOTE 3   A task type is a limited type (see 7.5), and hence precludes use of assignment_statements and predefined equality operators. If a programmer wants to write an application that stores and exchanges task identities, they can do so by defining an access type designating the corresponding task objects and by using access values for identification purposes. Assignment is available for such an access type as for any access type. Alternatively, if the implementation supports the Systems Programming Annex, the Identity attribute can be used for task identification (see C.7.1).
!corrigendum 9.6.1(90/2)
Replace the paragraph:
NOTE 1   The implementation-defined time zone of package Calendar may, but need not, be the local time zone. UTC_Time_Offset always returns the difference relative to the implementation-defined time zone of package Calendar. If UTC_Time_Offset does not raise Unknown_Zone_Error, UTC time can be safely calculated (within the accuracy of the underlying time-base).
by:
NOTE 1   The implementation-defined time zone of package Calendar can be the local time zone. Local_Time_Offset always returns the difference relative to the implementation-defined time zone of package Calendar. If Local_Time_Offset does not raise Unknown_Zone_Error, UTC time can be safely calculated (within the accuracy of the underlying time-base).
!corrigendum 9.9(7)
Replace the paragraph:
NOTE 2   Within task units, algorithms interrogating the attribute E'Count should take precautions to allow for the increase of the value of this attribute for incoming entry calls, and its decrease, for example with timed_entry_calls. Also, a conditional_entry_call may briefly increase this value, even if the conditional call is not accepted.
by:
NOTE 2   Within task units, by interrogating the attribute E'Count an algorithm can allow for the increase of the value of this attribute for incoming entry calls, and its decrease, for example with timed_entry_calls. A conditional_entry_call can also briefly increase this value, even if the conditional call is not accepted.
!corrigendum 9.9(8)
Replace the paragraph:
NOTE 3   Within protected units, algorithms interrogating the attribute E'Count in the entry_barrier for the entry E should take precautions to allow for the evaluation of the condition of the barrier both before and after queuing a given caller.
by:
NOTE 3   Within protected units, by interrogating the attribute E'Count in the entry_barrier for the entry E an algorithm can allow for the evaluation of the condition of the barrier both before and after queuing a given caller.
!corrigendum 10.1.1(27)
Replace the paragraph:
NOTE 1   A simple program may consist of a single compilation unit. A compilation need not have any compilation units; for example, its text can consist of pragmas.
by:
NOTE 1   A simple program can consist of a single compilation unit. A compilation can have no compilation units; for example, its text can consist of pragmas.
!corrigendum 10.1.4(9)
Replace the paragraph:
NOTE 2   An implementation may support a concept of a library, which contains library_items. If multiple libraries are supported, the implementation has to define how a single environment is constructed when a compilation unit is submitted to the compiler. Naming conflicts between different libraries might be resolved by treating each library as the root of a hierarchy of child library units.
by:
NOTE 2   An implementation can support a concept of a library, which contains library_items. If multiple libraries are supported, the implementation can document how a single environment is constructed when a compilation unit is submitted to the compiler. Naming conflicts between different libraries can, for example, be resolved by treating each library as the root of a hierarchy of child library units.
!corrigendum 10.2(34)
Replace the paragraph:
NOTE 4   A partition (active or otherwise) need not have a main subprogram. In such a case, all the work done by the partition would be done by elaboration of various library_items, and by tasks created by that elaboration. Passive partitions, which cannot have main subprograms, are defined in Annex E, "Distributed Systems".
by:
NOTE 4   A partition (active or otherwise) does not necessarily have a main subprogram. In such a case, all the work done by the partition would be done by elaboration of various library_items, and by tasks created by that elaboration. Passive partitions, which cannot have main subprograms, are defined in Annex E, "Distributed Systems".
!corrigendum 11.5(29)
Replace the paragraph:
NOTE 1   There is no guarantee that a suppressed check is actually removed; hence a pragma Suppress should be used only for efficiency reasons.
by:
NOTE 1   There is no guarantee that a suppressed check is actually removed; hence a pragma Suppress is useful only to improve efficiency.
!corrigendum 12.5.5(5/2)
Insert before the paragraph:
type Root_Work_Item is tagged private;
the new paragraph:
Example of the use of a generic with a formal interface type, to establish a standard interface that all tasks will implement so they can be managed appropriately by an application-specific scheduler:
!corrigendum 12.6(11)
Replace the paragraph:
NOTE 1   The matching rules for formal subprograms state requirements that are similar to those applying to subprogram_renaming_declarations (see 8.5.4). In particular, the name of a parameter of the formal subprogram [need not be the same as that of the corresponding parameter of the actual subprogram; similarly, for these parameters, default_expressions need not correspond.
by:
NOTE 1   The matching rules for formal subprograms state requirements that are similar to those applying to subprogram_renaming_declarations (see 8.5.4). In particular, the name of a parameter of the formal subprogram can be different from that of the corresponding parameter of the actual subprogram; similarly, for these parameters, default_expressions can be different.
!corrigendum 12.6(16.1/2)
Replace the paragraph:
NOTE 7   The subprogram declared by a formal_abstract_subprogram_declaration is an abstract subprogram. All calls on a subprogram declared by a formal_abstract_subprogram_declaration must be dispatching calls. See 3.9.3.
by:
NOTE 7   The subprogram declared by a formal_abstract_subprogram_declaration is an abstract subprogram. All calls on a subprogram declared by a formal_abstract_subprogram_declaration are limited to dispatching calls. See 3.9.3.
!corrigendum 13.4(11/5)
Replace the paragraph:
NOTE   Attribute Enum_Rep may be used to query the internal codes used for an enumeration type; attribute Enum_Val may be used to convert from an internal code to an enumeration value. The other attributes of the type, such as Succ, Pred, and Pos, are unaffected by the enumeration_representation_clause. For example, Pos always returns the position number, not the internal integer code that might have been specified in an enumeration_representation_clause.
by:
NOTE   Attribute Enum_Rep can be used to query the internal codes used for an enumeration type; attribute Enum_Val can be used to convert from an internal code to an enumeration value. The other attributes of the type, such as Succ, Pred, and Pos, are unaffected by an enumeration_representation_clause. For example, Pos always returns the position number, not {an}[the] internal integer code that {was}[might have been] specified in an enumeration_representation_clause.
!corrigendum 13.9.2(14/2)
Replace the paragraph:
NOTE 3   The Valid attribute may be used to check the result of calling an instance of Unchecked_Conversion (or any other operation that can return invalid values). However, an exception handler should also be provided because implementations are permitted to raise Constraint_Error or Program_Error if they detect the use of an invalid representation (see 13.9.1).
by:
NOTE 3   The Valid attribute can be used to check the result of calling an instance of Unchecked_Conversion (or any other operation that can return invalid values). However, an exception handler is still useful because implementations are permitted to raise Constraint_Error or Program_Error if they detect the use of an invalid representation (see 13.9.1).
!corrigendum 13.11(26)
Replace the paragraph:
NOTE 1   A user-defined storage pool type can be obtained by extending the Root_Storage_Pool type, and overriding the primitive subprograms Allocate, Deallocate, and Storage_Size. A user-defined storage pool can then be obtained by declaring an object of the type extension. The user can override Initialize and Finalize if there is any need for nontrivial initialization and finalization for a user-defined pool type. For example, Finalize might reclaim blocks of storage that are allocated separately from the pool object itself.
by:
NOTE 1   A user-defined storage pool type can be obtained by extending the Root_Storage_Pool type, and overriding the primitive subprograms Allocate, Deallocate, and Storage_Size. A user-defined storage pool can then be obtained by declaring an object of the type extension. The user can override Initialize and Finalize if there is any desire for nontrivial initialization and finalization for a user-defined pool type. For example, Finalize can reclaim blocks of storage that are allocated separately from the pool object itself.
!corrigendum 13.11.4(33/3)
Replace the paragraph:
NOTE 1   A user-defined storage pool type that supports subpools can be implemented by extending the Root_Storage_Pool_With_Subpools type, and overriding the primitive subprograms Create_Subpool, Allocate_From_Subpool, and Deallocate_Subpool. Create_Subpool should call Set_Pool_Of_Subpool before returning the subpool handle. To make use of such a pool, a user would declare an object of the type extension, use it to define the Storage_Pool attribute of one or more access types, and then call Create_Subpool to obtain subpool handles associated with the pool.
by:
NOTE 1   A user-defined storage pool type that supports subpools can be implemented by extending the Root_Storage_Pool_With_Subpools type, and overriding the primitive subprograms Create_Subpool, Allocate_From_Subpool, and Deallocate_Subpool. Create_Subpool is expected to call Set_Pool_Of_Subpool before returning the subpool handle. To make use of such a pool, a user can declare an object of the type extension, use it to define the Storage_Pool attribute of one or more access types, and then call Create_Subpool to obtain subpool handles associated with the pool.
!corrigendum 13.11.4(35/3)
Replace the paragraph:
NOTE 3   The pool implementor should override Default_Subpool_For_Pool if {they want} the pool is to support a default subpool for the pool. The implementor can override Deallocate if individual object reclamation is to be supported, and can override Storage_Size if there is some limit on the total size of the storage pool. The implementor can override Initialize and Finalize if there is any need for nontrivial initialization and finalization for the pool as a whole. For example, Finalize might reclaim blocks of storage that are allocated over and above the space occupied by the pool object itself. The pool implementor may extend the Root_Subpool type as necessary to carry additional information with each subpool provided by Create_Subpool.
by:
NOTE 3   The pool implementor can override Default_Subpool_For_Pool if they want the pool to support a default subpool for the pool. The implementor can override Deallocate if individual object reclamation is to be supported, and can override Storage_Size if there is some limit on the total size of the storage pool. The implementor can override Initialize and Finalize if there is any desire for nontrivial initialization and finalization for the pool as a whole. For example, Finalize can reclaim blocks of storage that are allocated over and above the space occupied by the pool object itself. The pool implementor can extend the Root_Subpool type as necessary to carry additional information with each subpool provided by Create_Subpool.
!corrigendum 13.13.2(57)
Replace the paragraph:
NOTE 1   For a definite subtype S of a type T, only T'Write and T'Read are needed to pass an arbitrary value of the subtype through a stream. For an indefinite subtype S of a type T, T'Output and T'Input will normally be needed, since T'Write and T'Read do not pass bounds, discriminants, or tags.
by:
NOTE 1   For a definite subtype S of a type T, only T'Write and T'Read are necessary to pass an arbitrary value of the subtype through a stream. For an indefinite subtype S of a type T, T'Output and T'Input will normally be necessary, since T'Write and T'Read do not pass bounds, discriminants, or tags.
!corrigendum A.4.3(107/3)
Replace the paragraph:
NOTE 1   In the Index and Count functions taking Pattern and Mapping parameters, the actual String parameter passed to Pattern should comprise characters occurring as target characters of the mapping. Otherwise, the pattern will not match.
by:
NOTE 1   In the Index and Count functions taking Pattern and Mapping parameters, for there to be a match, the actual String parameter passed to Pattern can contain only characters occurring as target characters of the mapping.
!corrigendum A.5.2(50)
Replace the paragraph:
NOTE 3   A given implementation of the Random function in Numerics.Float_Random may or may not be capable of delivering the values 0.0 or 1.0. Portable applications should assume that these values, or values sufficiently close to them to behave indistinguishably from them, can occur. If a sequence of random integers from some fixed range is needed, the application should use the Random function in an appropriate instantiation of Numerics.Discrete_Random, rather than transforming the result of the Random function in Numerics.Float_Random. However, some applications with unusual requirements, such as for a sequence of random integers each drawn from a different range, will find it more convenient to transform the result of the floating point Random function. For M >= 1, the expression
by:
NOTE 3   A given implementation of the Random function in Numerics.Float_Random is not guaranteed to be capable of delivering the values 0.0 or 1.0. Applications will be more portable if they assume that these values, or values sufficiently close to them to behave indistinguishably from them, can occur. If a sequence of random integers from some range is necessary, it is preferred that the application uses one of the Random functions in an appropriate instantiation of Numerics.Discrete_Random, rather than transforming the result of the Random function in Numerics.Float_Random.
!corrigendum A.16(131/2)
Replace the paragraph:
NOTE 5   To move a file or directory to a different location, use Rename. Most target systems will allow renaming of files from one directory to another. If the target file or directory might already exist, it first.
by:
NOTE 5   To move a file or directory to a different location, use Rename. Most target systems will allow renaming of files from one directory to another. If the target file or directory can already exist, delete it first.
!corrigendum B.3.1(60)
Replace the paragraph:
by:
!corrigendum D.2.5(18/2)
Replace the paragraph:
NOTE 1   Due to implementation constraints, the quantum value returned by Actual_Quantum might not be identical to that set with Set_Quantum.
by:
NOTE 1   Due to implementation constraints, the quantum value returned by Actual_Quantum can differ from that set with Set_Quantum.
!corrigendum D.3(21)
Replace the paragraph:
NOTE 4   When specifying the ceiling of a protected object, one should choose a value that is at least as high as the highest active priority at which tasks can be executing when they call protected operations of that object. In determining this value the following factors, which can affect active priority, should be considered: the effect of Set_Priority, nested protected operations, entry calls, task activation, and other implementation-defined factors.
by:
NOTE 4   When specifying the ceiling of a protected object, a correct value is one that is at least as high as the highest active priority at which tasks can be executing when they call protected operations of that object. In determining this value the following factors, which can affect active priority, are relevant: the effect of Set_Priority, nested protected operations, entry calls, task activation, and other implementation-defined factors.
!corrigendum D.5.1(19)
Replace the paragraph:
NOTE 5   Changing the priorities of a set of tasks can be performed by a series of calls to Set_Priority for each task separately. For this to work reliably, it should be done within a protected operation that has high enough ceiling priority to guarantee that the operation completes without being preempted by any of the affected tasks.
by:
NOTE 5   Changing the priorities of a set of tasks can be performed by a series of calls to Set_Priority for each task separately. This can be done reliably within a protected operation that has high enough ceiling priority to guarantee that the operation completes without being preempted by any of the affected tasks.
!corrigendum E.2.2(18)
Replace the paragraph:
NOTE 1   A remote types library unit need not be pure, and the types it defines may include levels of indirection implemented by using access types. User-specified Read and Write attributes (see 13.13.2) provide for sending values of such a type between active partitions, with Write marshalling the representation, and Read unmarshalling any levels of indirection.
by:
NOTE 1   A remote types library unit is not necessarily pure, and the types it defines can include levels of indirection implemented by using access types. User-specified Read and Write attributes (see 13.13.2) provide for sending values of such a type between active partitions, with Write marshalling the representation, and Read unmarshalling any levels of indirection.
!corrigendum H.5(7/2)
Replace the paragraph:
NOTE   An operation that causes a task to be blocked within a foreign language domain is not defined to be potentially blocking, and need not be detected.
by:
NOTE   An operation that causes a task to be blocked within a foreign language domain is not defined to be potentially blocking, and is unlikely to be detected.
!ASIS
No ASIS effect.
!ACATS test
No ACATS test should be needed, no change in meaning is intended and these are notes anyway.
!appendix

****************************************************************

Notes that need changing:

[I ignored the use of "needs" (in the sense of
desired - that word with that meaning is used extensively in the Directives)
and uses of "need" as a technical term (although some of them are shown in
this list). Some of these still need a suggested fix. Items added since
the original Tucker review are marked "Post-Tuck review".

Replacement of a single word with "can" have been moved to AI12-0440-1 (59
notes); some previously reviewed changes have been moved above.]


3.2.4 Subtype Predicates

Part of the Examples:

Text_IO (see A.10.1) could have used predicates to describe some common
exceptional conditions as follows:

["could have". I can't find a rewording that makes sense. Possibly we could
leave this one, since we were not explicitly asked to change any examples,
and this is expressing a hypothetical alternative, not any of the things not
allowed. But that's iffy.]

3.5.1 Enumeration Types

                                  Examples

Examples of enumeration types and subtypes:

        type Day        is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
        type Month_Name is (January, February, March, April, May, June, July,
                            August, September, October, November, December);

["May" should be OK here. I hope. :-)]


E.4.2 Example of Use of a Remote Access-to-Class-Wide Type

        -- Tape_Driver is not needed and thus not mentioned in the with_clause

[This use of "needed" is a use of a technical term and should not be changed.]

****************************************************************

From: Randy Brukardt
Sent: Friday, May 6, 2022  11:34 PM

The following items have come up since our meeting yesterday, that either were
not covered in the AIs or were changed from the AI version because of the "typo"
comments. Given that time is short before the FDIS needs to be delivered, I will
go ahead with these items unless someone makes an objection to one of them, in
which case we'll discuss it here. I'm providing these so there are no surprises.

[Just the cases that are relevant to this AI are shown here - Editor.]

#3 Brad's comment on 9.1(21/2) [AI12-0442-1]:

Brad wrote: "An application can't want things." The original fix was just to
replace "needs" with "wants", but his point is reasonable (at least for Ada 
programs :-). So a more extensive fix is needed. Brad's actual suggestion 
changed from second person to third person in the middle, so I changed his 
suggestion to the below. I ended up using "they", since ISO doesn't allow 
gender-specific words or pronouns. "It" doesn't work as we're talking about
a human now.

Modify 9.1(21/2):

    NOTE 3   A task type is a limited type (see 7.5), and hence precludes
    use of assignment_statements and predefined equality operators. If {a
    programmer wants to write }an application {that stores and 
    exchanges}[needs to store and exchange] task identities, {they}[it] can
    do so by defining an access type designating the corresponding task
    objects and by using access values for identification purposes. Assignment
    is available for such an access type as for any access type.
    Alternatively, if the implementation supports the Systems Programming
    Annex, the Identity attribute can be used for task identification (see
    C.7.1).

----

#4 Jeff's comment on C.7.2(31) [Also AI12-0442-1]

Jeff wrote: "!'m not sure what you're trying to say, I think either the "not" 
should stay or "until" should become "before", though the former seems more 
likely." The "not" can't stay, as that would still read like a negative 
permission (which is not allowed, at least not until the next edition of 
the Directives).

I didn't think there was any simple fix that made any sense, so I ended up 
reordering the entire sentence.

Modify C.7.2(31):

    NOTE 1   An attribute always exists (after instantiation), and has the
    initial value. {An implementation can avoid using}[It need not occupy]
    memory {to store the attribute value} until the first operation that
    [potentially] changes the attribute value. The same holds true after
    Reinitialize.

I dropped "potentially" since this is a runtime action, and thus it would be 
possible for the implementation to notice the default value being assigned 
and continue to avoid materializing the attribute. It's already a 
"possibility" statement because of the "can", we don't have to repeat that.

****************************************************************

From: Randy Brukardt
Sent: Thursday, June 9, 2022  1:39 AM

(Note: I'm sending this here as it *might* end up being addressed in the FDIS; 
if not, it will get moved to the new system.)

In applying wording changes, I happened to notice that the Random Number Note
3 (A.5.2(50-54)) gives bad advice. In particular, AI12-0144-1 added a discrete
random function Random with an explicit range as simple transformations, such
as the one given in this note, do not actually give a uniform distribution.
(The integer conversion is not necessarily uniform, even if the real input to
it is.)

Since we added this new routine specifically to handle the supposedly special
cases, the note should simply say that applications should use the Random
functionS (the S being new to the note) in an instance of Discrete.Random.

We don't necessarily need to fix this note in the FDIS (since it was been 
giving out bad advice since 1995, what's another 5 years? :-) OTOH, we know
the advice is bad (especially when the formula doesn't use an explicit
Truncate!), and we don't need it anymore, so we could just delete it (which
would seem to be in bounds for the FDIS).

If we were starting anew, perhaps we would explain why "obvious"
transformations are unlikely to be uniformly distributed, but that would be
too much for the FDIS, and might be too complex for the RM anyway. We could
just add a short AARM note instead (which we can always do).

It's not clear to me whether the advice about an exponential distribution is
actually correct, but it at least avoids the problems inherent from a type
conversion.

So this would end up looking something like (I'm not showing the extensive
deletion here):

---

NOTE 3 A given implementation of the Random function in Numerics.Float_Random
is not guaranteed to be capable of delivering the values 0.0 or 1.0.
Applications will be more portable if they assume that these values, or values
sufficiently close to them to behave indistinguishably from them, can occur.
If a sequence of random integers from some fixed range is necessary, the
application should use {one of} the Random function{s} in an appropriate
instantiation of Numerics.Discrete_Random, rather than transforming the 
result of the Random function in Numerics.Float_Random.

AARM Discussion: One might think that a simple transform like
         Integer(Float(M) * Random(G)) mod M
would give an uniform distribution from 0 .. M-1. But that only works if 
underlying random generator has a period of a multiple of M; otherwise, the
integer conversion would convert differing numbers of the original random
values into each result value, making the distribution not quite uniform.
Doing this correctly requires care, and thus a user should use the provided
functions (which hopefully have been implemented correctly, see AI12-0144-1
for a possible correct implementation) rather than "rolling their own"
solution.
End AARM Discussion.

Exponentially distributed (floating point) random numbers with mean and 
standard deviation 1.0 can be obtained by the transformation 

    -Log(Random(G) + Float'Model_Small)

where Log comes from Numerics.Elementary_Functions (see A.5.1); in this 
expression, the addition of Float'Model_Small avoids the exception that would
be raised were Log to be given the value zero, without affecting the result
(in most implementations) when Random returns a nonzero value. 

[In the above, parts of paragraphs 50 and 52 are deleted, along with all of
51. Argubly, the second part should now start a new note (that is, NOTE 4)
rather than be part of the first note, since it doesn't seem related to the
remaining part.]

------------

Should this be done now as part of the presentation changes for the FDIS, or
should we do a complete AI on the topic?? Should these be treated as two
separate notes??

****************************************************************

From: Tucker Taft
Sent: Thursday, June 9, 2022  7:26 AM

I would suggest postponing this and doing a "real" AI.  I see no urgency 
whatsoever, particularly since no one looks at the FDIS.  For advice, my guess
is folks use the online RM, which presumably will incorporate this sort of
update relatively soon, even if it isn't in the "official" Ada 2022 RM.

****************************************************************

From: Bob Duff
Sent: Thursday, June 9, 2022  7:40 AM

> In applying wording changes, I happened to notice that the Random 
> Number Note 3 (A.5.2(50-54)) gives bad advice. In particular, 
> AI12-0144-1 added a discrete random function Random with an explicit 
> range as simple transformations, such as the one given in this note, 
> do not actually give a uniform distribution. (The integer conversion 
> is not necessarily uniform, even if the real input to it is.)

Is the Advice really so bad?  It says, "...provided that M is not too large".
Doesn't that assumption imply that it's pretty close to uniform?

But Randy's suggested change is desirable anyway.  Now that we have a Random
function that takes a range, there's no need to be horsing around with
floating point.

P.S. I agree with Tucker that there's no hurry.

****************************************************************

From: Randy Brukardt
Sent: Thursday, June 9, 2022  1:51 PM

When I said "FDIS", I also meant the final published Ada 2022 RM. That's the 
version most people will be using for the next 5 years (at least until a 
Corrigendum is published, but experience suggests that many will still use 
the original version even after that). Sorry about any confusion on that 
point.

Few people use the online draft version, especially early in a cycle (nor 
should they), so the existence of that is pretty much irrelevant.

Does this change your answer? (I'm saying that to both Tuck and Bob)

As far as being Uniformly distributed, for many applications, close enough 
will cost money or allow security breaches. It's just plain bad to give such
advice without explaining that it is not exactly true. And a distribution is
not uniformly distributed if it is "close"; if the text said "close to a
uniform distribution" that would be better. But as Bob noted, there is no
reason to mention this at all anymore.

I do think we should fix it, but I agree that it is marginal -- if someone
with a high-security application is getting their numerics advice from the
RM, they do not really understand their job.

****************************************************************

From: Tucker Taft
Sent: Thursday, June 9, 2022  5:11 PM

> When I said "FDIS", I also meant the final published Ada 2022 RM. That's the
> version most people will be using for the next 5 years (at least until a 
> Corrigendum is published, but experience suggests that many will still use
> the original version even after that). Sorry about any confusion on that 
> point.
>
> Few people use the online draft version, especially early in a cycle (nor 
> should they), so the existence of that is pretty much irrelevant.

Not sure I agree, but in any case, I don't think the advice in a section about
Random numbers deserves our attention at this point.  We have bigger fish to
fry...

> Does this change your answer? (I'm saying that to both Tuck and Bob)

Not really.

****************************************************************

From: Tucker Taft
Sent: Thursday, June 9, 2022  5:14 PM

But let me add, if you (Randy, aka the Editor) are so inspired, then go for
it.  I don't think anyone will object either way.

****************************************************************

From: Randy Brukardt
Sent: Friday, June 10, 2022  12:47 AM

>>Few people use the online draft version, especially early in a cycle 
>>(nor should they), so the existence of that is pretty much irrelevant.

>Not sure I agree, ...

I'm not sure what you are not agreeing with, but I was simply referring to 
the numbers from our "usage of the Ada Standard" web report. Draft Ada 2022
usage is slowly growing, but still is below 10% of all usage of Ada Standards.
It's about the same as usage to Ada 2012+TC1, and about a third of the usage 
of Ada 2012.

Moreover, in the early days of that draft (which goes back to 2013), the usage
was 4-6%. The usage didn't really grow until 2020.

When that draft originally comes out, it is mainly aimed at implementers and
ACATS testers (who need to know the bleeding edge of Ada rules). For everyone
else, it is changing too much to be something to rely on. Once we get near the
end of a development cycle (like now), that will differ, of course.

The vast majority of use of Ada standards is to the major published versions 
(Ada 2005 and Ada 2012 primarily). People of course also use off-line versions,
but obviously those don't get updated either.

Getting back to the point, it seems likely that most users won't see the next 
standard until whenever we do the next revision.

Anyway, this is way too much detail (and mostly off topic!), but I just wanted 
to clarify what I was saying. It was carefully considered, not an off-the-cuff 
remark.

****************************************************************

From: Randy Brukardt
Sent: Friday, June 10, 2022  12:52 AM

>But let me add, if you (Randy, aka the Editor) are so inspired, then go 
>for it. I don't think anyone will object either way. 

That WAS the question, after all.

It's easier for me to do it now (no AI to write, no agenda item or meeting 
time spent, no minutes to write after a meeting, etc.). I can just stick it
in AI12-0442-1 (I think that's the right one) and do it immediately.

It sure seems more valuable to me (and to Ada users) than rewriting the 75th 
occurrence of "need not". :-) And I think as a pure deletion of part of a note
(and one that needed rewriting anyway), I think it is in bounds.

Does anyone actually object to doing this now???

****************************************************************

From: Tullio Vardanega
Sent: Friday, June 10, 2022  1:52 AM

In fact, I agree to Randy's stance here.

****************************************************************

From: Jeff Cousins
Sent: Friday, June 10, 2022  2:32 AM

Ok with me if you go for it.

****************************************************************

From: Randy Brukardt
Sent: Saturday, June 11, 2022  2:01 AM

Following are some fixes to the approved changed wording of the various FDIS 
AI. There also were a few typos in the AIs (stray brackets, missing words in
Editor's notes) that I won't bother to explain.

I'm not quite done applying the new wording, so there might be another item
or two on Monday, but I'm sending this now so that you can review it and
highlight any issues before I button this up.

[Editor's note: only issues relevant to this AI are shown here; others
are recorded in other relevant AIs.]

----

In AI12-0442-1, we have:

  Modify 3.5(58):

    NOTE 2   For a subtype of a scalar type, the result delivered by the
    attributes Succ, Pred, and Value {can be outside}[might not belong to]
    the subtype; similarly, the actual parameters of the attributes Succ,
    Pred, and Image {are also allowed to be outside}[need not belong to]
    the subtype.

This AI is about notes, where "may" is not allowed. However, "is allowed" is
defined to be a synonym of "may", so "are also allowed" isn't allowed (pun
intended) either. I replaced this by:

  Modify 3.5(58):

    NOTE 2   For a subtype of a scalar type, the result delivered by the
    attributes Succ, Pred, and Value {can be outside}[might not belong to]
    the subtype; similarly, the actual parameters of the attributes Succ,
    Pred, and Image {can also be outside}[need not belong to] the subtype.

which is shorter anyway.

The same issue, with the same fix, also occurs in 3.5.5(12).

-----

The Note 6.1.2(44/5) says:

NOTE For an example of the use of these aspects and attributes, see the Vector 
container definition in A.18.2.

But 6.1.2 doesn't contain any attributes anymore, so this should just say:

NOTE For an example of the use of these aspects, see the Vector container 
definition in A.18.2.

I added this to AI12-0442-1.

In so doing, I noticed that 6.1.2(18/5) was in that AI, but that is not a 
note or example -- it is in the wrong AI. So I moved that paragraph to 
AI12-0445-1.

---------------

In AI12-0442-1, D.3(21) reads:

    NOTE 4   When specifying the ceiling of a protected object, [one should
    choose] a {correct }value that is {one that is }at least as high
    as the highest active priority
    at which tasks can be executing when they call protected operations of
    that object. In determining this value the following factors, which
    can affect active priority, {are relevant}[should be considered]:
    the effect of Set_Priority, nested protected operations, entry calls,
    task activation, and other implementation-defined factors.

There is an extra "that" remaining here, this should be:

    NOTE 4   When specifying the ceiling of a protected object, [one should
    choose] a {correct }value {is one }that is at least as high
    as the highest active priority
    at which tasks can be executing when they call protected operations of
    that object. In determining this value the following factors, which
    can affect active priority, {are relevant}[should be considered]:
    the effect of Set_Priority, nested protected operations, entry calls,
    task activation, and other implementation-defined factors.

-------------------

In AI12-0442-1, 12.6(11) is modified to remove "need not" as follows:

    NOTE 1   The matching rules for formal subprograms state requirements
    that are similar to those applying to subprogram_renaming_declarations
    (see 8.5.4). In particular, the name of a parameter of the formal 
    subprogram {can be different from}[need not be the same as] that of the
    corresponding parameter of the actual subprogram; similarly, for these 
    parameters, default_expressions need not correspond.

But there is a second occurrence of "need not" that also needs to be replaced.

    NOTE 1   The matching rules for formal subprograms state requirements
    that are similar to those applying to subprogram_renaming_declarations
    (see 8.5.4). In particular, the name of a parameter of the formal 
    subprogram {can be different from}[need not be the same as] that of the
    corresponding parameter of the actual subprogram; similarly, for these 
    parameters, default_expressions {can be different}[need not correspond].

****************************************************************

From: Tucker Taft
Sent: Saturday, June 11, 2022  8:14 AM

All look good to me.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, June 14, 2022  8:36 PM

Having finally finished applying all of the wording changes, I was able to
check the result for words we're not supposed to be using. And surprise,
there still were a dozen or so uses of words we were trying to eliminate.
Some of those were errors applying changes (often cases where there were
two changes in a paragraph, but only one change was applied). The rest are
detailed below.

Please read and comment (if needed) on these ASAP as I will be finishing 
this project in the next few days (I hope!!).

[Editor's note: only issues relevant to this AI are shown here; others
are recorded in other relevant AIs.]

In AI12-0442-1, 3.9.3(16) says:

    NOTE 3   Notes on the example: Given the above abstract type, one
    {can}[could then] derive various (nonabstract) extensions of the type,
    representing alternative implementations of a set. One {possibility 
    is to}[might] use a bit vector, but impose an upper bound on the largest
    element representable, while another possible implementation 
    is a hash table, trading off space for flexibility.

But this is not the original wording for the last part of this paragraph; it
originally said "might use". So the correct change is:

    NOTE 3   Notes on the example: Given the above abstract type, one
    {can}[could then] derive various (nonabstract) extensions of the type,
    representing alternative implementations of a set. One {possibility 
    is to}[might] use a bit vector, but impose an upper bound on the largest
    element representable, while another {possible implementation 
    is}[might use] a hash table, trading off space for flexibility.

----------------

3.9.4(33/2) abuses "must", and needs to be reworded.

   An interface such as Queue can be used directly as the parent of a new type
   (as shown here), or can be used as a progenitor when a type is derived.
In
   either case, the primitive operations of the interface are inherited. For
   Queue, the implementation of the four inherited routines {will be required
   to}[must] be provided. Inside the call of Transfer, calls will dispatch to
   the implementations of Append and Remove_First for type Fast_Food_Queue.

This was added to AI12-0442-1.

----------------

A number of Annex M (summary of Implementation-Defined and Implementation
Advice) items contain banned words (as the original text did). I've fixed
these  similarly to the base text (and did not otherwise document them, as
is usual as they are considered non-normative).

----------------

The introduction to each subclause of Annex M contains a "must". I replaced 
this with "is required to". This is not ideal, but as we are talking about 
requirements given elsewhere, it's hard to find any language that doesn't 
seem like itself a requirement.

I put these 4 (!) changes into AI12-0442-1 (as this is not supposed to be 
normative text, it follows from requirements elsewhere). (Note: If ISO
complains about this Annex, I suggest we drop it altogether from the ISO
version.)

----------------

9.9(8) has almost the same wording as 9.9(7), and it needs the same fixes,
giving:

    NOTE 3   Within protected units, {by}[algorithms] interrogating the
    attribute E'Count in the entry_barrier for the entry E {an algorithm
    can}[should take precautions to] allow for the evaluation of the
    condition of the barrier both before and after queuing a given caller. 

This was added to AI12-0442-1.

----------------

Arrrggghhh! The rewrite of A.5.2(50), the infamous Random number paragraph,
did not get rid of "should". While I still think we need a "Usage Advice"
category (so we can use "should" in cases like this), the best I can do is
to express it as a "preference" (since a note cannot give a recommendation,
period).

Here's my fix:

    NOTE 3   A given implementation of the Random function in
    Numerics.Float_Random {is not guaranteed to}[may or may not]
    be capable of delivering the values 0.0 or 1.0. {Applications will be
    more portable if they}[Portable applications should] assume
    that these values, or values sufficiently close to them to behave
    indistinguishably from them, can occur. If a sequence of random
    integers from some [fixed ]range is {necessary}[needed], {it is
    preferred that }the application [should use]{uses one of} the
    Random function{s} in an appropriate
    instantiation of Numerics.Discrete_Random, rather than transforming
    the result of the Random function in Numerics.Float_Random.[ However,
    some applications
    with unusual requirements, such as for a sequence of random integers
    each drawn from a different range, will find it more convenient to
    transform the result of the floating point Random function. For M >=
    1, the expression]

****************************************************************

From: Jeff Cousins
Sent: Wednesday, June 15, 2022  2:35 AM

Thanks Randy, looks good.

****************************************************************

From: Tucker Taft
Sent: Wednesday, June 15, 2022  5:05 PM

Most seem fine.  I have one comment on some awkward wording below.

>3.9.4(33/2) abuses "must", and needs to be reworded.
>
>   An interface such as Queue can be used directly as the parent of a new type
>   (as shown here), or can be used as a progenitor when a type is derived. In
>   either case, the primitive operations of the interface are inherited. For
>   Queue, the implementation of the four inherited routines {will be required
>   to}[must] be provided. Inside the call of Transfer, calls will dispatch to
>   the implementations of Append and Remove_First for type Fast_Food_Queue.

This seems a bit awkward.  Perhaps more simply:


For Queue, the four inherited routines have to be overridden.  Inside the call
of Transfer ...


 Not sure whether this uses any disallowed words...

****************************************************************

From: Randy Brukardt
Sent: Wednesday, June 15, 2022  7:27 PM

"Has to" is a synonym of "shall", I presume the plural form "have to" is also 
treated the same. "Shall" is not allowed here as this is associated with an
example. As a practical matter, it is nearly impossible to talk about
consequences of requirements in notes, because that necessarily uses the same
wording as a requirement. 
 
I have thought about registering a formal complaint with JTC1 (would have to go
through SC 22, of course) about this problem, since it seems to be very
important to be able to have notes about consequences and such consequences
shouldn't be confused with actual requirements. ("can" works for possible
consequences, of course, but when a consequence is inevitable, no wording
exists that is both allowed and doesn't already reflect a requirement).
 
In the above, I tried to use "will be required" to attempt to make it clear
that this is not a requirement itself, but it is very close to the phrasing of
a requirement and I'm dubious that it really would work if checked. I don't
think it is likely that anyone will check all of the wording in detail; most
likely, a check for unallowed words (like "might") will be done and that's
about it. Checking notes is especially hard, there are too many to do by hand,
so one would require a specialized tool to check them all -- I have such a
tool but I doubt that ISO does.
 
The only real solution to problems like this is to avoid the notes and
examples that cause them. Probably would need to drop all notes that talk
about consequences from the ISO version. But I don't expect it to come to
that (at least not for that reason).
 
If you can come up with some wording that doesn't use any phrases like the
following:
   is to
   is required to
   it is required that
   has to
   only … is permitted
   it is necessary
then please suggest it.

****************************************************************

From: Tucker Taft
Sent: Sunday, June 19, 2022  3:28 PM

>>This seems a bit awkward.  Perhaps more simply:
>>
>>For Queue, the four inherited routines have to be overridden.  Inside the
>> call of Transfer ...

Perhaps:

  For Queue, the four inherited routines will necessarily be overridden.
  Inside the call ...

****************************************************************

From: Randy Brukardt
Sent: Monday, June 20, 2022  9:12 PM

That's probably better. While "necessary" is one of the words to avoid here,
"necessarily" is not the same thing.

****************************************************************

Questions? Ask the ACAA Technical Agent