!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.) **************************************************************** From: Steve Baird Sent: Friday, January 11, 2019 5:39 PM > 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. In particular, we might want this AI to say something about images for System.Address (at least in the case where the implementation advice suggesting that System.Address should be declared as a private type is followed) and for Ada.Tags.Tag. >> For each language-defined container type T (i.e., each of the >> Vector, ... > 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. Makes sense. The key point is, as you point out, to treat container types consistently with concrete composite types. >> 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. The other alternative I was considering (as opposed to an AARM note) was to say nothing at all on the grounds that this should just be common sense. Making it implementation advice seems more like an attempt to legislate good taste. **************************************************************** From: Randy Brukardt Sent: Friday, January 11, 2019 6:17 PM > > 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. > > In particular, we might want this AI to say something about images for > System.Address (at least in the case where the implementation advice > suggesting that System.Address should be declared as a private type is > followed) and for Ada.Tags.Tag. I would say that type Imaginary (since it is supposed to be numeric) also qualifies. Bounded_String and Unbounded_String also seem important (in that they're heavily used), but maybe not as much since there are other ways to get an string value from them. ... > >> 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. > > The other alternative I was considering (as opposed to an AARM note) > was to say nothing at all on the grounds that this should just be > common sense. Making it implementation advice seems more like an > attempt to legislate good taste. Since when do implementers have common sense or good taste?? :-) I think this is important enough to at least mention, since I can see (from the implementation prespective) reasons for doing the easiest thing -- which is nothing and just letting the default implementation (which would show all of the private components) show through. But this is *not* what we want, nor, I suspect, what most users would want. And it's important to tell the Ada user that the intent isn't to let random implementation junk show through, thus suggesting IA. Maybe just a Note would be better. There definitely is value is lightly explaining what we consider good taste. They're always welcome to ignore IA, after all (it's never bothered me :-). **************************************************************** From: Steve Baird Sent: Friday, January 11, 2019 6:49 PM > Maybe just a Note would be better. I said an AARM note or perhaps nothing at all, you said Implementation Advice . A Note sounds like a good way to split the difference. **************************************************************** From: Tucker Taft Sent: Friday, January 11, 2019 9:21 PM We almost never use Notes directed at implementations. Notes are almost always for the user. I would stick with Implementation Advice or an AARM note. At this point, I suggest we leave the final decision to an ARG meeting. ****************************************************************