AI22-0119-1
!standard 3.6(13) 24-11-03 AI22-0119-1/03
!standard 4.10(18/5)
!standard 5.5.2(11/5)
!standard 5.5.2(11.1/5)
!standard 13.13.2(9/5)
!standard 13.13.2(9.1/5)
!standard 13.13.2(9.2/5)
!class binding interpretation 24-10-24
!status work item 25-03-19
!status ARG Approved 13-0-1 24-10-31
!status work item 24-10-24
!status received 24-02-14
!assigned author Tucker Taft
!submitter Christoph Grein
!priority Low
!difficulty Easy
!qualifier Clarification
!subject Canonical order should be defined once and only referenced later
The phrase "canonical order of components" as used by Generalized Loop Iteration, Put_Image, and T'Write, should be defined in one place (3.6(13)) and used without repeating the definition.
Currently the phrase "canonical order of components" appears in the description of Generalized Loop Iteration, the Put_Image attribute, and the Write attribute.
Should these definitions be combined into a single definition, and then merely referenced later? (Yes.)
Perhaps a more fundamental issue is that the use of "canonical order" in the description of Put_Image is misleading (4.10(18/5)), since in the other two places it is used (T'Write and Generalized Loop Iteration) it is related to the issue of multidimensional arrays, and whether they are iterated in column-major or row-major order, which is determined by whether or not the Fortran convention has been specified. For Put_Image, multidimensional arrays are intended to use nested aggregate notation, so this issue of row-major vs. column-major order is irrelevant.
It might still be useful to have the "canonical order" term for nonarray composite types, but it must be used appropriately to avoid confusion with the row-major vs. column-major issue. Should we generalize the term to apply to nonarray composite types, including all discriminated types? (Yes.)
The term "canonical order" should be generalized to apply to nonarray composite types. Relative to arrays, it addresses the issue of layout of multidimensional arrays. For other sorts of composite types, it generally means declaration order, but with discriminants always coming first. It should be defined in the sections where we define array types, record types, and discriminant parts, and then used for things like positional aggregates, Put_Image, etc
Modify 3.4(14):
Declarations of components, protected subprograms, and entries, whether implicit or explicit, occur immediately within the declarative region of the type, in the order indicated above{; the canonical order of components of the derived type is determined by the relative position of the component declarations within this order. [Redundant: Only the discriminant declarations, if any, are visible within} [, following] the parent subtype_indication.]
Add after 3.6(13):
The canonical order of components of an array is the order in which components are produced by iterating over the indices of the array, either in row-major order, where the last dimension varies fastest, or column-major order, where the first dimension varies fastest, as determined by the convention of the array (see B.1). For language-defined conventions, column-major order is used with the Fortran Convention (see B.5);[a] row-major order is used for other language-defined conventions.
Modify 3.7(25):
Each value of a discriminated type includes a value for each component of the type that does not depend on a discriminant[Redundant:; this includes the discriminants themselves]. The values of discriminants determine which other component values are present in the value of the discriminated type. {The canonical order of components of any type with discriminants starts with the discriminants, in the order of their declaration within the known_discriminant_part.}
Add after 3.8(15):
The canonical order of components of a record type are the discriminants, if any[Redundant:, in the order of their declaration within a known_discriminant_part], followed by the nondiscriminant components, if any, in the order of their declaration.
Modify 4.10(18/5):
If the default implementation of Put_Image writes components{ of a nonarray composite type T, the components are written in their canonical order (see 3.4, 3.7, and 3.8).}[, the order in which components are written is the same canonical order in which components of a composite type T are written out by the default implementation of T'Write. [Redundant: This is also the order that is used in determining the meaning of a positional aggregate of type T.]][b][c][d][e][f][g]
Modify 4.10(19/5):
For an array type T, the default implementation of T'Put_Image generates an image based on named (not positional) array aggregate syntax (with '[' and ']' as the delimiters) using calls to the Put_Image procedures of the index type(s) and the element type to generate images for values of those types. {The components are written in increasing index order at each level, using a nested syntax for a multidimensional array, as in a multidimensional array aggregate.}
Modify 5.5.2(11/5):
For an array component iterator, … Otherwise, the sequence_of_statements is conditionally executed with the loop parameter denoting each component of the array for the loop, using [a canonical]{the canonical} order of components{ (see 3.6)}[, which is last dimension varying fastest (unless the array has convention Fortran, in which case it is first dimension varying fastest)]. For a forward array component iterator, …
Modify 13.13.2(9/5):
For nonderived elementary types, Read reads (and Write writes) the number of stream elements implied by the Stream_Size for the type T; the representation of those stream elements is implementation defined. For nonderived composite types, the Write or Read attribute for each component (excluding those, if any, that are not components of the nominal type of the object) is called in canonical order{ (see 3.6 and 3.8)}[, which is last dimension varying fastest for an array (unless the convention of the array is Fortran, in which case it is first dimension varying fastest), and positional aggregate order for a record]. Bounds are not included in the stream if T is an array type. If T is a discriminated type, discriminants are included only if they have defaults. If T is a tagged type, the tag is not included.
We have tried to unify the various definitions of canonical order as they appear in the description of Put_Image, Generalized Loop Iterators, and T'Write. This required distinguishing how the term is used for records from how it is used for arrays, where it "flattens" out the order of components of a multidimensional array either in row-major or column-major order, depending on the convention of the array type. We have moved the definition to Chapter 3, located with the definition of derived types, array types, record types, and discriminated types.
The author of this AI chose not to use "canonical order" for the description of positional record aggregates, but we could consider making changes there as well.
This is intended to be merely a presentation improvement, so should have no effect on ACATS tests, except perhaps in terms of vocabulary.
This issue was identified during the discussion of ARG GitHub issue # 85.
[a]Someday this should be defined in B.5, making this statement redundant.
[b]For the redo of this AI to actually fix the bug (as opposed to just changing wording for some unknown reason), I would seriously consider getting rid of this paragraph altogether. The array case is already handled separately in paragraph 19 (since "canonical order" is wrong there), and the only other two places that components are written is paragraph 21 and 24 (the other rules are either part of another rule, or there are no components involved). 24 only involves discriminants, so that could be very simple ("in the order of the declaration of the discriminants"). That means the only case needing some fairly complex wording seems to be paragraph 21. Just put that wording with paragraph 21, either as part of it or following it. And this paragraph can bite the dust.
[c]Sounds like a plan. Should we try to produce a short AI and have a letter ballot so it gets into the Corrigendum? I'll create some suggested wording in my next reply.
[d]Modify 4.10(21/6) as follows:
For a record type (or, as indicated above, certain composite derived types), or a protected type, the default implementation of T'Put_Image generates an image based on named (not positional) record aggregate syntax (except that for a protected type, the initial left parenthesis is followed by "PROTECTED with "). Component names are displayed in upper case, following the rules for the image of an enumeration value. Component values are displayed via calls to the Put_Image procedure of the component type. {Components are displayed in the order they occur within the declarative region of the type (see 8.1 and 3.4).}
[e]Modify 4.10(24/5):
For a discriminated task type, the default implementation of T'Put_Image also includes discriminant values{, in the order they occur within the known_discriminant_part}, as in:
[f]So there is no reference to the term canonical order. However, the last sentence above "{Components are displayed in the order they occur within the declarative region of the type (see 8.1 and 3.4).}" sounds much like the proposed addition after 3.8(15).
The trigger of the whole AI 119 is AI 118 and especially 4.10(18/5). I understand that the latter paragraph will now be completely removed.
[g]Yes. The new AI is AI22-0132-1, which can be found here: https://docs.google.com/document/d/17ba1NWpQGTIp3keBwbETlAeSBys8UY11xXvaUrlPvuM