!standard 5.5.2(2/3) 19-01-11 AI12-0304-1/01 !standard 5.5.2(5/4) !standard 5.5.2(7/3) !class Amendment 19-01-11 !status work item 19-01-11 !status received 19-01-10 !priority Low !difficulty Easy !subject Image attributes of language-defined types !summary Image attributes of some language-defined private types are specified. !problem Now that we have Image attributes for all types, we need to decide what (if anything) we are going to say about the Image for each language-defined private type. !proposal (See Summary.) !wording Append to the end of the new (as of AI12-0020) 4.10 Images section. For any language-defined scalar type T, T'Put_Image shall not be specified. Implementation Permissions For each language-defined non-scalar type T, T'Put_Image may be specified. AARM note: This permission applies, in particular, to non-scalar types declared in language-defined generic packages, and to any language-defined private type which an implementation chooses to complete as a scalar type. Implementation Advice For each language-defined container type T (i.e., each of the Vector, List, Map, Set, Tree, and Holder types defined in the various children of Ada.Containers), T'Put_Image should be specified so that T'Image produces a result consistent with array aggregate syntax (using "[" and "]" as delimiters) as follows: - Map images should be consistent with named array aggregate syntax, using key value images in place of discrete choice names. For example, "[Key1 => Value1, Key2 => Value2]". AARM Note: There is no recommendation about the order in which key/element pairs occur within a map image. In the case of multiple key values whose corresponding element values have the same image, there is no recommendation about factoring (e.g., generating "Key1 | Key2 => Some_Value" instead of "Key1 => Some_Value, Key2 => Some_Value"). - Set, List, and Holder images should be consistent with positional array aggregate syntax. List elements should occur in order within an image of a list. AARM Note: There is no recommendation about the order in which set elements occur within the image of a set. - Tree images (and images of subtrees of trees) should be consistent with positional array aggregate syntax. For example, "[[1, 2], [111, 222, 333]]". For each language-defined type T that has a primitive language-defined Image function whose profile is type conformant with that of T'Image (e.g., Ada.Numerics.Float_Random.State has such an Image function), T'Put_Image should be specified so that T'Image yields the same result as that Image function. AARM Note: For each language-defined private type T, implementations are encouraged to ensure that T'Image generates images that would be meaningful based only on the relevant public interfaces, as opposed to requiring knowledge of the implementation of the private type. !discussion One could imagine going into great detail specifying the behavior of the image attributes of all of the various non-scalar predefined types. That does not seem like a good idea (do we really want to spend any time considering what images should look like for the private type Ada.Text_IO.Editing.Picture?). But the container types do seem to be of particular interest, so perhaps we ought to say something about them. (Incidentally, is there anything that we want to say about the Image attributes of the various cursor types?). --- The first new rule (the prohibition on specifying T'Put_Image for a language-defined scalar type T) is intended to ensure that the behavior of T'Image (and T'Wide_Image, etc.) remains unchanged from what it was before the Put_Image aspect was introduced. In two places, the wording says "T'Put_Image should be specified so that" some condition is satisfied. I presume that it goes without saying that there is no need to specify T'Put_Image if the default aspect value satisfies the condition - this wording is not intended to impose a requirement that T'Put_Image must be explicitly specified in the case where the default implementation would be just fine. [Editor's note: I think the recently added "as-if" AARM Note {A(5.d/5)} would cover this. The only way this would matter is if there exists some program that could tell the difference. I don't know of such a way, but perhaps the author does.] !ASIS No ASIS effect. !ACATS test ACATS B- and C-Tests are needed to check that the new capabilities are supported. !appendix From: Steve Baird Sent: Thursday, January 10, 2019 2:31 PM The definition of Image attributes for non-scalar types (AI12-0020) implicitly introduces questions about the behavior of the Image attributes of predefined types. One of my homework assignments is to open an AI to deal with this question, so I am doing that here. One could imagine going into great detail specifying the behavior of the image attributes of all of the various non-scalar predefined types. That does not seem like a good idea (do we really want to spend any time considering what images should look like for the private type Ada.Text_IO.Editing.Picture?). But the container types do seem to be of particular interest, so perhaps we ought to say something about them. (Incidentally, is there anything that we want to say about the Image attributes of the various cursor types?). With all of this in mind, I propose the following (!wording only at this point). The first rule (the prohibition on specifying T'Put_Image for a language-defined scalar type T) is intended to ensure that the behavior of T'Image (and T'Wide_Image, etc.) remains unchanged from what it was before the Put_Image aspect was introduced. In two places, the wording says "T'Put_Image should be specified so that" some condition is satisfied. I presume that it goes without saying that there is no need to specify T'Put_Image if the default aspect value satisfies the condition - this wording is not intended to impose a requirement that T'Put_Image must be explicitly specified in the case where the default implementation would be just fine. ==== !wording Append to the end of the new (as of AI12-0020) 4.10 Images section. For any language-defined scalar type T, T'Put_Image shall not be specified. Implementation Permissions For each language-defined non-scalar type T, T'Put_Image may be specified. AARM note: This permission applies, in particular, to non-scalar types declared in language-defined generic packages, and to any language-defined private type which an implementation chooses to complete as a scalar type. Implementation Advice For each language-defined container type T (i.e., each of the Vector, List, Map, Set, Tree, and Holder types defined in the various children of Ada.Containers), T'Put_Image should be specified so that T'Image produces a result consistent with array aggregate syntax (using "[" and "]" as delimiters) as follows: - Map images should be consistent with named array aggregate syntax, using key value images in place of discrete choice names. For example, "[Key1 => Value1, Key2 => Value2]". AARM Note: There is no recommendation about the order in which key/element pairs occur within a map image. In the case of multiple key values whose corresponding element values have the same image, there is no recommendation about factoring (e.g., generating "Key1 | Key2 => Some_Value" instead of "Key1 => Some_Value, Key2 => Some_Value"). - Set, List, and Holder images should be consistent with positional array aggregate syntax. List elements should occur in order within an image of a list. The image of an empty holder should be "[]". AARM Note: There is no recommendation about the order in which set elements occur within the image of a set. - Tree images (and images of subtrees of trees) should be consistent with positional array aggregate syntax. For example, "[[1, 2], [111, 222, 333]]". For each language-defined type T that has a primitive language-defined Image function whose profile is type conformant with that of T'Image (e.g., Ada.Numerics.Float_Random.State has such an Image function), T'Put_Image should be specified so that T'Image yields the same result as that Image function. AARM Note: For each language-defined private type T, implementations are encouraged to ensure that T'Image generates images that would be meaningful based only on the relevant public interfaces, as opposed to requiring knowledge of the implementation of the private type. **************************************************************** From: Tucker Taft Sent: Thursday, January 10, 2019 2:40 PM Looks like a good start. **************************************************************** From: Steve Baird Sent: Thursday, January 10, 2019 4:51 PM > - Set, List, and Holder images should be consistent with >          positional array aggregate syntax. List elements should >          occur in order within an image of a list. We should probably add another rule here: The image of an empty holder should be "[]". One might argue that this is already implied by the preceding "should be consistent with positional array aggregate syntax" advice, but Randy pointed out (in private communication) that > An empty holder isn't quite the same as a null array (it's more like > an array of length one with null in place of the element) So it seems worthwhile to say *something* about the case of an empty holder. **************************************************************** From: Randy Brukardt Sent: Friday, January 11, 2019 1:55 AM A few thoughts while I should be doing something else (like creating an agenda). ... > One could imagine going into great detail specifying the behavior of > the image attributes of all of the various non-scalar predefined > types. > > That does not seem like a good idea (do we really want to spend any > time considering what images should look like for the private type > Ada.Text_IO.Editing.Picture?). I think it might be a good idea to make a list of every language-defined type. Trying to remember them from memory is bound to miss some. For instance, I just ran across private type Imaginary in the complex package. Bizarrely, the private part of that package is specified. It is supposed to completed with a real type. It would seem reasonable to require the image of that to be the real value. I do agree that for many types, the Image is questionable. What is the Image of a File_Type? The Name might be a good idea, but it also might be useful to show some of the underlying implementation (such as a file handle). Probably not worth deciding. ... BTW, I used most of your message as the !discussion of the AI. I know better than to expect I'll get more without asking several times. ;-) And I can't wait tonight anyway. ... > Implementation Advice > > For each language-defined container type T (i.e., each of the Vector, We don't say "i.e." in the Standard. No one is quite sure if it is used it right, and is easier to say "that is" anyway. More important: Personally, I would prefer this is an Implementation Requirement. If we think it is important to specify the Image for an array (and we did), we ought to give the same treatment to the containers. After all, a Vector is as close as we can make it to an array with a sticky lower bound. You've specified to about the same level as we specified the array and record aggregates, so it should be fine as a requirement. It definitely seems valuable to be able to depend on the Image much like one can depend on the streaming to work. And if an implementation wants to show some debugging info, they shouldn't pollute the user view with that. ... > For each language-defined type T that has a primitive > language-defined Image function whose profile is type conformant with > that of T'Image (e.g., Ada.Numerics.Float_Random.State has such an > Image function), T'Put_Image should be specified so that T'Image > yields the same result as that Image function. This seems like a good idea. Unfortunately, Imaginary does have an Image function. (I have no idea why Imaginary is private and Complex is visible, that seems bizzare.) > AARM Note: > For each language-defined private type T, implementations are > encouraged to ensure that T'Image generates images that would be > meaningful based only on the relevant public interfaces, as opposed > to requiring knowledge of the implementation of the private type. *This* seems like relevant Implementation Advice. **************************************************************** From: Randy Brukardt Sent: Friday, January 11, 2019 2:19 AM ... > I think it might be a good idea to make a list of every > language-defined type. Trying to remember them from memory is bound to > miss some. I just remembered that I had to make such a list for nonlimited private types for the ACATS objectives. (There's a rule that every nonlimited private type has an equality that composes properly.) Here's the list of nonlimited types: System.Addess Ada.String.Maps.Character_Set Ada.String.Wide_Maps.Wide_Character_Set Ada.String.Wide_Wide_Maps.Wide_Wide_Character_Set Bounded_String (from an instance Ada.String.Bounded) Ada.Strings.Unbounded.Unbounded_String Ada.Task_Identification.Task_Id Cursor (from an instance of an Ada.Containers) Wide_Bounded_String (from an instance Ada.Strings.Wide_Bounded) Ada.Strings.Wide_Unbounded.Wide_Unbounded_String Wide_Wide_Bounded_String Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Unbounded_String State (from an instance Ada.Numerics.Discrete_Random) Ada.Numerics.Float_Random.State Ada.Real_Time.Time_Span Ada.Real_Time.Time Imaginary (from an instance Ada.Numerics.Generic_Complex_Types) Ada.Calendar.Time Ada.Exceptions.Exception_Id Interfaces.C.Strings.chars_ptr Ada.Execution_Time.CPU_Time Ada.Text_IO.Editing.Picture --- Limited private types are probably less likely to need an image. These include Random Generators, the various File_Types, Directories Search_Type and Directory_Entry_Type, Exceptions Exception_Occurrence, Root_Subpool in Subpools (this is more of an interface), Root_Stream_Type, Limited_Controlled (another interface), and a bunch of types in Annex D (Suspension_Object, Synchronous_Barrier, Timer, Timing_Event, Group_Budget, and Dispatching_Domain). (I just searched for "limited private", so I suppose it's possible I missed something.) ****************************************************************