Version 1.5 of 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 WG9 Approved 22-06-22
!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); --
Rectangle : Matrix(1 .. 20, 1 .. 30);
Inverse : Matrix(1 .. N, 1 .. N); --
["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 ... --
for J in Code range Fix .. Dec loop ... --
for J in Code'(Fix) .. Dec loop ... --
[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; --
...
--
My_Complex_Array (Count) := (Re => @.Re**2 - @.Im**2,
Im => 2.0 * @.Re * @.Im);
--
[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
--
--
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:
- the allocated object should be freed by the programmer via a call
of Free, not by a called C function.
by:
- the allocated object can be freed by the programmer via a call
of Free, rather than by calling a C function.
!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