CVS difference for ai12s/ai12-0020-1.txt

Differences between 1.9 and version 1.10
Log of other versions for file ai12s/ai12-0020-1.txt

--- ai12s/ai12-0020-1.txt	2018/06/12 05:28:46	1.9
+++ ai12s/ai12-0020-1.txt	2018/06/15 02:05:26	1.10
@@ -1,4 +1,4 @@
-!standard 4.10(0)                                     18-06-06    AI12-0020-1/03
+!standard 4.10(0)                                     18-06-14    AI12-0020-1/04
 !standard 3.5(27.1/2)
 !standard 3.5(55.1/5)
 !standard 3.5(55.2/5)
@@ -25,7 +25,7 @@
 
 !proposal
 
-T'Image is defined for all non-abstract types (including class-wide types).
+T'Image is defined for (almost) all types (including class-wide types).
 Ditto for T'Wide_Image and T'Wide_Wide_Image.
 
 All of these are defined in terms of T'Put_Image, a stream-like attribute
@@ -111,16 +111,18 @@
 
    4.10  Images
 
-   For every subtype S of a non-universal type T, the following
-   type-related operational attributes are defined:
+   Static Semantics
 
+    For every subtype S of a non-universal type T, the following
+    type-related operational attributes are defined:
+
       S'Put_Image
          S'Put_Image denotes a procedure with the following specification:
             S'Put_Image
                (Arg : T; Stream : access Counted_Stream'Class);
  	    
       The default implementation of S'Put_Image writes out
-      (using Wide_Wide_String'Write and or Wide_Wide_String'Output)
+      (using Wide_Wide_String'Write)
       an image of the value of Arg; that is, a Wide_Wide_String
       representing the value in display form.
       This is described in more detail later in this section.
@@ -200,8 +202,8 @@
         S'Max_Image_Elements yields the value of T's Max_Image_Elements
         aspect. The type of both the aspect and the attribute is
         Ada.Streams.Stream_Offset.
-        The Max_Image_Elements attribute may be specified for any type
-        type T either via an attribute_definition_clause, via an
+        The Max_Image_Elements attribute may be specified for any
+        type T either via an attribute_definition_clause, via
         an aspect_specification specifying the Put_Image aspect of the type,
 	or (in the case of a derived type) via inheritance.
         If specified, the aspect_definition shall be a static expression in
@@ -213,15 +215,36 @@
 	If no value for the aspect is specified and no such pragma exists,
 	then the value of the aspect is -1.
 
-    Pragma Default_Max_Image_Elements is a configuration pragma which
-    takes a single argument, a static expression of type
-    Ada.Streams.Stream_Offset in the range
-    -1 .. Ada.Streams.Stream_Element_Offset'Last.
-    Pragma Default_Max_Image_Elements shall not be used other than
-    as a configuration pragma. If more than one Default_Max_Image_Elements
+   Syntax
+
+    The form of a Default_Max_Image_Elements pragma is
+    is follows:
+
+      pragma Default_Max_Image_Elements (*stream_offset_*expression);
+
+   Name Resolution Rules
+
+    The expected type for a stream_offset_expression is
+    Streams.Stream_Offset.
+
+   Legality Rules
+
+    Default_Max_Image_Elements is a configuration pragma, and shall
+    not be used other than as a configuration pragma.
+    The *stream_offset_*expression shall be a static expressions in
+    the range -1 .. Streams.Stream_Element_Offset'Last.
+ 
+    If more than one Default_Max_Image_Elements
     pragma applies to a given compilation unit, then they shall all
     specify equal (static) Stream_Element_Offset values.
 
+   Static semantics
+
+    [A Default_Max_Image_Elements pragma participates in
+    determining the Max_Image_Elements aspect(s) of zero or more
+    types as described above.]
+
+
     The behavior of the default implementation of S'Put_Image depends
     on the class of T. For an elementary type, the implementation is
     equivalent to
@@ -240,31 +263,55 @@
        that there should be no change in the behavior of existing
        programs as a result of these changes. End AARM Discussion.
 
+       [Editor's note: The AARM notes for scalar types come from the original
+       definition of Image; they're unchanged here.]
+
        For an integer type, the image written out is the corresponding
        decimal literal, without underlines, leading zeros, exponent, or
        trailing spaces, but with a single leading character that is either
        a minus sign or a space.
 
+         AARM Implementation Note: If the machine supports negative zeros for
+         signed integer types, it is not specified whether " 0" or "–0" should
+         be returned for negative zero. We don't have enough experience with
+         such machines to know what is appropriate, and what other languages
+         do. In any case, the implementation should be consistent.
+
        For an enumeration type, the image written out is either the
        corresponding identifier in upper case or the corresponding character
        literal (including the two apostrophes); neither leading nor trailing
        spaces are included. For a nongraphic character (a value of a character
        type that has no enumeration literal associated with it), the value is
        a corresponding language-defined name in upper case (for example,
-       the image of the nongraphic character identified as nul is “NUL” —
+       the image of the nongraphic character identified as nul is "NUL" —
        the quotes are not part of the image).
 
+         AARM Implementation Note: For an enumeration type T that has "holes"
+         (caused by an enumeration_representation_clause), T'Put_Image should
+         raise Program_Error if the value is one of the holes (which is a
+         bounded error anyway, since holes can be generated only via
+         uninitialized variables and similar things).
+
        For a floating point type, the image written out is a decimal real
        literal best approximating the value (rounded away from zero if
        halfway between) with a single leading character that is either a minus
        sign or a space, a single digit (that is nonzero unless the value is
-       zero), a decimal point, S'Digits–1 (see 3.5.8) digits after the
+       zero), a decimal point, S'Digits-1 (see 3.5.8) digits after the
        decimal point (but one if S'Digits is one), an upper case E, the sign
-       of the exponent (either + or –), and two or more digits (with leading
+       of the exponent (either + or -), and two or more digits (with leading
        zeros if necessary) representing the exponent. If S'Signed_Zeros is
        True, then the leading character is a minus sign for a negatively
        signed zero.
 
+         AARM To be honest: Leading zeros are present in the exponent only if
+         necessary to make the exponent at least two digits.
+
+         AARM Reason: This image is intended to conform to that produced by
+         Text_IO.Float_IO.Put in its default format.
+
+         AARM Implementation Note: The rounding direction is specified here to
+         ensure portability of output results.
+
        For a fixed point type, the image written out is a decimal real literal
        best approximating the value (rounded away from zero if halfway between)
        with a single leading character that is either a minus sign or a space,
@@ -272,6 +319,16 @@
        zeros), a decimal point, and S'Aft (see 3.5.10) digits after the
        decimal point.
 
+         AARM Reason: This image is intended to conform to that produced by
+         Text_IO.Fixed_IO.Put.
+
+         AARM Implementation Note: The rounding direction is specified here to
+         ensure portability of output results.
+
+         AARM Implementation Note: For a machine that supports negative zeros,
+         it is not specified whether " 0.000" or "–0.000" is returned. See
+         corresponding comment above about integer types with signed zeros.
+
        For an access type (named or anonymous), the image written out depends
        on whether the value is null. If it is null, then the image is "NULL".
        Otherwise the image is a sequence of uppercase hexadecimal digits
@@ -294,8 +351,13 @@
    the index type(s) and the element type to generate images for values
    of those type.
    This might generate an image such as
-       "( 1 => ( 1 => ( 123 => True,  124 => False),  2 => ( 123 => False,  124 => False)),  2 => ( 1 => ( 123 => True,  124 => True),  2 => ( 123 => True,  124 => False)))"
-   .
+    ( 1 => ( 1 => ( 123 => True,  124 => False)
+             2 => ( 123 => False,  124 => False)),
+      2 => ( 1 => ( 123 => True,  124 => True),
+             2 => ( 123 => True,  124 => False)))
+   except with each sequence of spaces and line breaks replaced
+   with a single space (with two spaces in the case of the spaces
+   between a comma and an integer literal).
    The case of a null array is handled specially, using ranges for
    index bounds and "<>" as a syntactic component-value placeholder.
    This might generate an image such as
@@ -321,7 +383,7 @@
    .
 
    For a (specific) type extension, the default implementation of T'Put_Image
-   depends  on whether there exists a non-interface ancestor of T (other than
+   depends  on whether there exists a noninterface ancestor of T (other than
    T itself) for which the Put_Image aspect has been [explicitly] specified.
    If so, then T'Put image will generate an image based on extension aggregate
    syntax where the ancestor type of the extension aggregate is the
@@ -345,7 +407,7 @@
    The image written out for a record having no components (including
    any interface type) is "(NULL RECORD)".
    In the case of a protected type T, a call to the default implementation
-   of T'Put_Image begins only one protected (readonly) action.
+   of T'Put_Image begins only one protected (read-only) action.
 
    [AARM Implementation Note: The expected, but
    not required, implementation model for generating the image of a
@@ -463,8 +525,77 @@
 Bounded_Stream objects should be implemented without implicit pointers or
 dynamic allocation.
 
+  AARM Reason: The Counted_Streams.Bounded package is provided in order to
+  make available an alternative to the Counted_Streams.Unbounded
+  package which gives more predictable memory usage.
+
 !discussion
 
+
+The expected (although not required) implementation of the package 
+Ada.Streams.Counted_Streams.Unbounded involves dynamic storage allocation of some
+kind, perhaps accompanied with uses of controlled types.
+
+For some applications with high integrity/reliability requirements, those 
+requirements (more specifically, requirements about predictable memory 
+utilization) might preclude use of this package.
+
+Nonetheless, we would like such applications to be able to use T'Image for a 
+non-scalar type T without having to override the default implementation of 
+T'Put_Image.
+
+That is the motivation for introducing
+    a) The package Ada.Streams.Counted_Streams.Bounded and its
+       associated implementation advice.
+    b) The aspect (and attribute) Max_Image_Elements
+    c) The pragma Default_Max_Image_Elements.
+    d) The interaction (for a given type T) between
+       T'Max_Image_Elements and the default implementation
+       of T'Put_Image .
+
+An application can specify T'Max_Image_Elements either explicitly or via a 
+Default_Max_Image_Elements configuration pragma. Having done that, the default
+implementation of T'Put_Image will reference Counted_Streams.Bounded instead 
+of Counted_Streams.Unbounded.
+
+This will achieve the desired goal.
+
+The cost is that the burden is on the user to choose a "good" value for 
+T'Max_Image_Elements. If the value is too small, then a call to T'Put_Image
+may fail; if the value is too big, then the storage requirements of a call 
+to T'Put_Image may be unnecessarily large.
+
+----
+
+Put_Image is user-specifiable; Wide_Wide_Image is not.
+
+One could imagine instead allowing user-specified Wide_Wide_Image attributes 
+and not bothering to define User_Put_Image at all.
+
+The drawback of this approach is that it would could introduce, at least for
+some compilers, lots of copying.
+
+Given
+    type T is record F1, F2, F3 : Integer; end record;
+
+the default implementation of T'Wide_Wide_Image could have been defined to be 
+something like
+
+      return "(F1 => " &
+               Arg.F1'Wide_Wide_Image &
+               ", F2 => " &
+               Arg.F2'Wide_Wide_Image &
+               ", F3 => &
+               Arg.F3'Wide_Wide_Image &
+               ")";
+
+but that's a lot of concatenation; the situation for arrays would be even worse.
+
+Furthermore, the two Ada.Streams.Counted_Streams packages (Bounded and 
+Unbounded) seem like they will be useful in their own right.
+
+----
+
 This change does introduce an obscure incompatibility having to do with
 implicit dereferencing when the prefix of an Image (or Wide_Image, or
 Wide_Wide_Image) attribute is an object of an access-to-scalar type.
@@ -2203,5 +2334,676 @@
 of T'Put_Image begins only one protected (readonly) action.“ – “read-only”.
 
 Item (Item'First .. Last)'Length” (two places) – what is meant by this??
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 11, 2018  9:34 PM
+
+...        
+  zero), a decimal point, S'Digits–1 (see 3.5.8) digits after the
+  decimal point (but one if S'Digits is one), an upper case E, the sign
+  of the exponent (either + or –),” – what are the – meant to be?
+
+That's most likely the Unicode @endash, which doesn't cut-and-paste into
+pure ASCII properly. It should just appear here as "-". That happens also
+for the angled quote marks (which should never appear in Ada code samples)
+among other things. I try to fix them, but it's a losing battle.
+
+***************************************************************
+
+From: Steve Baird
+Sent: Wednesday, June 13, 2018  5:46 PM
+
+>> (C2)
+>>      Pragma Default_Max_Image_Elements is a configuration pragma 
+>> which
+>>      takes a single argument, a static expression of type
+>>      Ada.Streams.Stream_Offset in the range
+>>      -1 .. Ada.Streams.Stream_Element_Offset'Last.
+>>      Pragma Default_Max_Image_Elements shall not be used other than
+>>      as a configuration pragma. If more than one 
+>> Default_Max_Image_Elements
+>>      pragma applies to a given compilation unit, then they shall all
+>>      specify equal (static) Stream_Element_Offset values.
+>>
+>> I'm not sure that we can use such a short definition of a pragma. All 
+>> pragmas that I can think of give a syntax definition; even List and 
+>> Page do that. So I think we need to define the "form" of this pragma, 
+>> with a Syntax portion. (Ugh, I know.)
+>>
+> 
+> Really? I guess I can't argue that this one is even simpler than 
+> pragma Page, so ok.
+> 
+Ok, use J.15.12 (pragma Relative_Deadline) or D.2.2 (pragma
+Priority_Specific_Dispatching) as templates (in particular, with respect to
+fonts) and replace the above with
+
+     Syntax
+
+     The form of a Default_Max_Image_Elements pragma is
+     as follows:
+
+       pragma Default_Max_Image_Elements (stream_offset_expression);
+
+    Name Resolution Rules
+       The expected type for a stream_offset_expression is
+       Ada.Streams.Stream_Offset
+
+(do we, by convention, omit the "Ada." in "Ada.Streams"?)
+
+    Legality Rules:
+       Default_Max_Image_Elements is a configuration pragma, and shall
+       not be used other than as a configuration pragma.
+       The stream_offset_expression shall be a static expressions in
+       the range -1 .. Ada.Streams.Stream_Element_Offset'Last.
+
+       If more than one Default_Max_Image_Elements
+       pragma applies to a given compilation unit, then they shall all
+       specify equal (static) Stream_Element_Offset values.
+
+    Static semantics
+       [A Default_Max_Image_Elements pragma participates in
+       determining the Max_Image_Elements aspect(s) of zero or more
+       types as described above.]
+
+>> (C3) You probably ought to add a paragraph to the discussion 
+>> describing the model and use of Bounded_Stream. I know why it's there 
+>> ('cause you told me), but it doesn't seem to be mentioned anywhere in 
+>> the AI.
+>>
+> 
+> It's there for the same reason that we provide the bounded containers.
+> 
+
+Note that the only text along these lines that we have for bounded containers 
+is A.18's AARM text
+    "Similarly, a separate bounded version is provided in order to give
+    more predictable memory usage."
+
+So immediately after the proposed implementation advice
+
+    Bounded_Stream objects should be implemented without implicit
+    pointers or dynamic allocation.
+
+We add
+
+    [AARM: The Counted_Streams.Bounded package is provided in order to
+    make available an alternative to the Counted_Streams.Unbounded
+    package which gives more predictable memory usage.]
+
+
+>> (C4) You deleted all of the AARM notes along with the original 
+>> definition of Wide_Wide_Image, but you didn't put them back into the 
+>> discussion of the default images of the various types. That seems 
+>> like (relatively) important information about topics like Negative 
+>> Zeros and rounding is getting lost.
+>> The Impldef information for Wide_Image and Image definitely has to 
+>> move (so the annex M.1 listing doesn't lose them). A similar thought 
+>> applies to 55.b/5.
+>>
+> 
+> Good point.
+> 
+
+In the current RM, we have
+
+   Implementation Note: If the machine supports negative zeros for signed
+   integer types, it is not specified whether " 0" or "–0" should be
+   returned for negative zero. We don't have enough experience with such
+   machines to know what is appropriate, and what other languages do. In
+   any case, the implementation should be consistent.
+
+occurring immediately after
+
+    The image of an integer value is ... either a minus sign or a space.
+
+So that is also where the implementation note goes in the new wording.
+
+Similarly, in the current RM we have
+
+    Implementation Note: For an enumeration type T that has “holes”
+    (caused by an enumeration_representation_clause), T'Wide_Image should
+    raise Program_Error if the value is one of the holes (which is a
+    bounded error anyway, since holes can be generated only via
+    uninitialized variables and similar things).
+
+occurring immediately after
+
+     The image of an enumeration value is ... “NUL” — the quotes are not
+     part of the image).
+
+so that's also where it goes in the new wording.
+
+And in the current RM we have
+
+    To be honest: Leading zeros are present in the exponent only if
+    necessary to make the exponent at least two digits.
+
+    Reason: This image is intended to conform to that produced by
+    Text_IO.Float_IO.Put in its default format.
+
+    Implementation Note: The rounding direction is specified here to
+    ensure portability of output results.
+
+occurring immediately after
+
+    The image of a floating point value is ...  a negatively signed zero.
+
+so that's also where it goes in the new wording.
+
+And in the current RM we have
+
+     Reason: This image is intended to conform to that produced by
+     Text_IO.Fixed_IO.Put.
+
+     Implementation Note: The rounding direction is specified here to
+     ensure portability of output results.
+
+    Implementation Note: For a machine that supports negative zeros, it
+    is not specified whether " 0.000" or "–0.000" is returned. See
+    corresponding comment above about integer types with signed zeros.
+
+occurring immediately after
+
+    The image of a fixed point value is ... the decimal point.
+
+so that's also where it goes in the new wording.
+
+>> (C5) Under the image of arrays, you have:
+>>
+>>     This might generate an image such as
+>>         "( 1 => ( 1 => ( 123 => True,  124 => False),  2 => ( 123 => 
+>> False,
+>> 124 => False)),  2 => ( 1 => ( 123 => True,  124 => True),  2 => ( 
+>> 123 => True,  124 => False)))"
+>>
+>> This is too long for a line in the RM. It will get folded somehow, 
+>> and that would probably give an incorrect interpretation of the 
+>> actual result.
+>> (I see
+>> this e-mail editor folded it!) I don't know what the appropriate 
+>> answer is here, but this can't be in the RM as written; we need an 
+>> alternative that fits in one line or additional wording to explain 
+>> the extra line breaks.
+>>
+> 
+> Like you, I'm not sure what to do here. Some thought is required.
+> 
+
+How about:
+
+  This might generate an image such as
+    ( 1 => ( 1 => ( 123 => True,  124 => False)
+             2 => ( 123 => False,  124 => False)),
+      2 => ( 1 => ( 123 => True,  124 => True),
+             2 => ( 123 => True,  124 => False)))
+   except with each sequence of spaces and line breaks replaced
+   with a single space (with two spaces in the case of the spaces
+   between a comma and an integer literal).
+
+This isn't ideal; I'm (very) open to suggestions.
+
+=======
+>> “The default implementation of S'Put_Image writes out (using
+>> Wide_Wide_String'Write and or Wide_Wide_String'Output)”
+> – maybe “and/or”  or just “or”?
+
+Or maybe just eliminate the reference to Wide_Wide_String'Output, so it 
+becomes just "using Wide_Wide_String'Write". I'm not sure what I was thinking
+of when I mentioned 'Output.
+
+> duplicate
+> “type” and duplicate “an”.
+
+Good catch.
+
+
+>  what are the – meant to be?
+
+I think Randy explained this stuff.
+
+Alternatively, a comic-strip character hit his thumb with a hammer.
+
+> if 248-1 is approved, we could use “null array” rather than “<>”.
+
+I thought about that and decided that we (or at least I) don't want to use
+that syntax even if the AI is approved because it doesn't allow specifying the
+bounds.
+
+We can discuss this further, of course, if there is interest.
+
+>  depends  on whether there exists a non-interface ancestor” – I like
+>> the use of English English, but I’m sure Gary would object to the hyphen.
+
+Good catch. The current RM currently has 3 uses of "noninterface" and
+no uses of "non-interface".
 
-*************************************************************
+
+> T'Put_Image begins only one protected (readonly) action.“ – “read-only”.
+
+Agreed. Take the hyphen I used in "non-interface" and move it over here.
+
+
+> “Item (Item'First .. Last)'Length” (two places) – what is meant by this??
+
+In the first occurrence, we've got
+
+    overriding
+    procedure Read (
+     Stream : in out Unbounded_Stream;
+     Item   : out Stream_Element_Array;
+     Last   : out Stream_Element_Offset)
+     with Post =>
+        Element_Count (Stream) =
+        Element_Count (Stream)'Old - Item (Item'First .. Last)'Length;
+
+The postcondition says that the final Element_Count is equal to the
+old Element_Count minus the number of stream elements that were read.
+The expression in question
+     Item (Item'First .. Last)'Length
+yields the number of stream elements that were read (at least that
+was my intent).
+
+The second occurrence is the same thing except in the Bounded package
+instead of the Unbounded package.
+
+***************************************************************
+
+From: Randy Brukaardt
+Sent: Thursday, June 14, 2018  5:17 PM
+
+> >> (C2)
+...
+> Ok, use J.15.12 (pragma Relative_Deadline) or D.2.2 (pragma
+> Priority_Specific_Dispatching) as templates (in particular, with 
+> respect to fonts) and replace the above with
+
+I take it from this that you are expecting me (your overworked editor :-) to
+make these updates? I'll do them, but I surely don't want to duplicate effort.
+
+>      Syntax
+> 
+>      The form of a Default_Max_Image_Elements pragma is
+>      as follows:
+> 
+>        pragma Default_Max_Image_Elements (stream_offset_expression);
+> 
+>     Name Resolution Rules
+>        The expected type for a stream_offset_expression is
+>        Ada.Streams.Stream_Offset
+> 
+> (do we, by convention, omit the "Ada." in "Ada.Streams"?)
+
+Usually, a convention I hate and often forget. My recollection was that it was 
+in response to a complaint that Ada 9x was too wordy; it eliminated some words 
+without actually requiring any effort to do so. And it has no descernable 
+effect on the size of the Standard (any gains made disappear in clause breaks
+and the like). Grump.
+ 
+...
+> >> (C3) You probably ought to add a paragraph to the discussion 
+> >> describing the model and use of Bounded_Stream. I know why it's 
+> >> there ('cause you told me), but it doesn't seem to be mentioned 
+> >> anywhere in the AI.
+> >>
+> > 
+> > It's there for the same reason that we provide the bounded containers.
+> > 
+> 
+> Note that the only text along these lines that we have for bounded 
+> containers is A.18's AARM text
+>     "Similarly, a separate bounded version is provided in order to give
+>     more predictable memory usage."
+> 
+> So immediately after the proposed implementation advice
+> 
+>     Bounded_Stream objects should be implemented without implicit
+>     pointers or dynamic allocation.
+> 
+> We add
+> 
+>     [AARM: The Counted_Streams.Bounded package is provided in order to
+>     make available an alternative to the Counted_Streams.Unbounded
+>     package which gives more predictable memory usage.]
+
+Fine, but you totally missed my point. You have a pragma and a package and 
+some other disconnected things, but nowhere you do you layout the model. At a
+minimum, we need something like:
+
+   The default model of Put_Image uses unbounded streams, which necessarily 
+   involves some dynamic memory allocation. Since Ada is widely used by 
+   systems that require predictable memory usage, we provide an alternative 
+   model for Put_Image that provides that. Such a user should apply 
+   Silly_Pragma (** too lazy to look it up **) as a configuration pragma to 
+   their entire system. This causes Bounded_Stream (*** and other facts?? **)
+   to be used for all calls to Put_Image rather than Unbounded_Streams, 
+   providing the needed memory predicability.
+
+I'm certain this requires more fleshing out (there's some value associated 
+with Silly_Pragma, it needs to be mentioned here).
+
+...
+> >> This is too long for a line in the RM. It will get folded somehow, 
+> >> and that would probably give an incorrect interpretation of the 
+> >> actual result.
+> >> (I see
+> >> this e-mail editor folded it!) I don't know what the appropriate 
+> >> answer is here, but this can't be in the RM as written; we need an 
+> >> alternative that fits in one line or additional wording to explain 
+> >> the extra line breaks.
+> >>
+> > 
+> > Like you, I'm not sure what to do here. Some thought is required.
+> > 
+> 
+> How about:
+> 
+>   This might generate an image such as
+>     ( 1 => ( 1 => ( 123 => True,  124 => False)
+>              2 => ( 123 => False,  124 => False)),
+>       2 => ( 1 => ( 123 => True,  124 => True),
+>              2 => ( 123 => True,  124 => False)))
+>    except with each sequence of spaces and line breaks replaced
+>    with a single space (with two spaces in the case of the spaces
+>    between a comma and an integer literal).
+> 
+> This isn't ideal; I'm (very) open to suggestions.
+
+It's OK enough by me, absent better ideas.
+
+
+====
+...
+> >  what are the – meant to be?
+> 
+> I think Randy explained this stuff.
+> 
+> Alternatively, a comic-strip character hit his thumb with a hammer.
+
+LoL.
+
+...
+> > “Item (Item'First .. Last)'Length” (two places) – what is meant by this??
+> 
+> In the first occurrence, we've got
+> 
+>     overriding
+>     procedure Read (
+>      Stream : in out Unbounded_Stream;
+>      Item   : out Stream_Element_Array;
+>      Last   : out Stream_Element_Offset)
+>      with Post =>
+>         Element_Count (Stream) =
+>         Element_Count (Stream)'Old - Item (Item'First .. Last)'Length;
+> 
+> The postcondition says that the final Element_Count is equal to the 
+> old Element_Count minus the number of stream elements that were read.
+> The expression in question
+>      Item (Item'First .. Last)'Length
+> yields the number of stream elements that were read (at least that was 
+> my intent).
+> 
+> The second occurrence is the same thing except in the Bounded package 
+> instead of the Unbounded package.
+
+Sure, but I wondered why you wrote 'Length rather than just writing the 
+answer. That is, for any array with integer indices,
+
+    Arr(A..B)'Length == (if A <= B then B - A + 1 else 0)
+
+The attribute form requires evaluating the prefix and the condition, but in 
+this case we know that Last + 1 >= Item'First, so the evaluating neither is 
+necessary. (And I doubt that a compiler can figure that out -- it would 
+require detailed rummaging in the body of the routine -- SPARK may be able 
+to, of course.)
+
+So I probably would have written:
+
+    Last - Item'First + 1 -- Number of characters read (or returned?)
+
+for this value. I suppose your original expression is closer to 
+self-documenting, but even that isn't the case judging from Jeff's 
+question.
+
+***************************************************************
+
+From: Steve Baird
+Sent: Thursday, June 14, 2018  6:06 PM
+
+>>>> (C2)
+> ...
+>> Ok, use J.15.12 (pragma Relative_Deadline) or D.2.2 (pragma
+>> Priority_Specific_Dispatching) as templates (in particular, with 
+>> respect to fonts) and replace the above with
+> 
+> I take it from this that you are expecting me (your overworked editor :-)
+> to make these updates? I'll do them, but I surely don't want to duplicate
+> effort.
+
+I accept your generous offer.
+
+>
+> ...
+>>>> (C3) You probably ought to add a paragraph to the discussion 
+>>>> describing the model and use of Bounded_Stream. I know why it's 
+>>>> there ('cause you told me), but it doesn't seem to be mentioned 
+>>>> anywhere in the AI.
+
+> 
+> Fine, but you totally missed my point. You have a pragma and a package and 
+> some other disconnected things, but nowhere you do you layout the model. 
+> At a minimum, we need something like: ...
+> 
+
+I'll agree that we need some such text after you show me the corresponding 
+text for the bounded containers (and this is not just rhetorical - there is
+a real chance that the wording is there and I overlooked it). If we didn't 
+need such wording in the case of the containers, then IMO we don't need it 
+here.
+
+> 
+> So I probably would have written:
+> 
+>      Last - Item'First + 1 -- Number of characters read (or returned?)
+> 
+> for this value. I suppose your original expression is closer to 
+> self-documenting, but even that isn't the case judging from Jeff's 
+> question.
+
+I say stick with what I proposed for now in the AI and we can flip a coin in 
+Lisbon. Either way is fine with me, but I have a weak preference for the way I
+originally wrote it.
+
+Thanks for the feedback,
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, June 14, 2018  6:17 PM
+
+> I'll agree that we need some such text after you show me the 
+> corresponding text for the bounded containers (and this is 
+> not just rhetorical - there is a real chance that the wording 
+> is there and I overlooked it). If we didn't need such wording 
+> in the case of the containers, then IMO we don't need it here.
+
+These aare completely different cases, IMHO. You don't need to use a
+configuration pragma to use a bounded container; you just use it if you
+like. You could do that with the bounded marshalling stream, of course, but
+the point here is to allow Image to be used without forcing dynamic
+allocation. The AI needs to say that somewhere!
+
+Moreover, I'm talking about adding text into the !discussion to explain what
+the heck this pragma and Bounded_Stream type are doing there in the first
+place. It doesn't need to be in the RM (you often seem to be so fixed on the
+details that nothing else matters, but I want to be able to read one of
+these AIs in ten years and have some idea why we chose the design we did --
+and it's clear that others do read AIs for that sort of information).
+*Nothing* should appear in an AI without some explanation of why its there
+and what it's for.
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, June 14, 2018  6:21 PM
+
+> I'll agree that we need some such text after you show me the 
+> corresponding text for the bounded containers (and this is not just 
+> rhetorical - there is a real chance that the wording is there and I 
+> overlooked it). If we didn't need such wording in the case of the 
+> containers, then IMO we don't need it here.
+
+Ignoring how silly a request this is, here's the start of the !discussion in
+AI05-0001-1:
+
+  The bounded forms are intended to bring determinism to the storage 
+  requirements of the various container forms. To this end, each bounded form 
+  includes Implementation Advice that no dynamic allocation or pointers are 
+  used to implement them. Thus, the bounded forms should be usable even in 
+  high-integrity contexts where dynamic allocation is forbidden.
+
+I am looking for something on this line explaining how the pragma and the 
+stream work together to provide this behavior for Image. Few people are going 
+to be able to figure it out on their own.
+
+***************************************************************
+
+From: Steve Baird
+Sent: Thursday, June 14, 2018  6:33 PM
+
+> Moreover, I'm talking about adding text into the !discussion to 
+> explain what the heck this pragma and Bounded_Stream type are doing 
+> there in the first place. It doesn't need to be in the RM (you often 
+> seem to be so fixed on the details that nothing else matters, but I 
+> want to be able to read one of these AIs in ten years and have some 
+> idea why we chose the design we did -- and it's clear that others do read
+> AIs for that sort of information).
+> *Nothing*  should appear in an AI without some explanation of why its 
+> there and what it's for.
+
+Ok, I completely agree about !discussion . I thought you were talking about 
+AARM wording.
+
+I'll propose something shortly.
+
+Incidentally, since we are talking about things other than the !wording 
+section, the !proposal section currently begins with
+
+   T'Image is defined for all non-abstract types
+
+and this should probably be replaced with something like
+
+   T'Image is defined for (almost) all types.
+
+***************************************************************
+
+From: Steve Baird
+Sent: Thursday, June 14, 2018  7:13 PM
+
+> Ok, I completely agree about !discussion . I thought you were talking 
+> about AARM wording.
+> 
+> I'll propose something shortly.
+
+!discussion
+
+The expected (although not required) implementation of the package 
+Ada.Streams.Counted_Streams.Unbounded involves dynamic storage allocation of some
+kind, perhaps accompanied with uses of controlled types.
+
+For some applications with high integrity/reliability requirements, those 
+requirements (more specifically, requirements about predictable memory 
+utilization) might preclude use of this package.
+
+Nonetheless, we would like such applications to be able to use T'Image for a 
+non-scalar type T without having to override the default implementation of 
+T'Put_Image.
+
+That is the motivation for introducing
+    a) The package Ada.Streams.Counted_Streams.Bounded and its
+       associated implementation advice.
+    b) The aspect (and attribute) Max_Image_Elements
+    c) The pragma Default_Max_Image_Elements.
+    d) The interaction (for a given type T) between
+       T'Max_Image_Elements and the default implementation
+       of T'Put_Image .
+
+An application can specify T'Max_Image_Elements either explicitly or via a 
+Default_Max_Image_Elements configuration pragma. Having done that, the default
+implementation of T'Put_Image will reference Counted_Streams.Bounded instead 
+of Counted_Streams.Unbounded.
+
+This will achieve the desired goal.
+
+The cost is that the burden is on the user to choose a "good" value for 
+T'Max_Image_Elements. If the value is too small, then a call to T'Put_Image
+may fail; if the value is too big, then the storage requirements of a call 
+to T'Put_Image may be unnecessarily large.
+
+====
+
+Put_Image is user-specifiable; Wide_Wide_Image is not.
+
+One could imagine instead allowing user-specified Wide_Wide_Image attributes 
+and not bothering to define User_Put_Image at all.
+
+The drawback of this approach is that it would could introduce, at least for
+some compilers, lots of copying.
+
+Given
+    type T is record F1, F2, F3 : Integer; end record;
+
+the default implementation of T'Wide_Wide_Image could have been defined to be 
+something like
+
+      return "(F1 => " &
+               Arg.F1'Wide_Wide_Image &
+               ", F2 => " &
+               Arg.F2'Wide_Wide_Image &
+               ", F3 => &
+               Arg.F3'Wide_Wide_Image &
+               ")";
+
+but that's a lot of concatenation; the situation for arrays would be even worse.
+
+Furthermore, the two Ada.Streams.Counted_Streams packages (Bounded and 
+Unbounded) seem like they will be useful in their own right.
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, June 14, 2018  8:20 PM
+
+...
+> Incidentally, since we are talking about things other than the 
+> !wording section, the !proposal section currently begins with
+> 
+>    T'Image is defined for all non-abstract types
+> 
+> and this should probably be replaced with something like
+> 
+>    T'Image is defined for (almost) all types.
+
+Humm. You describe Put_Image as working like streams. You have no rules for 
+abstract types, that seems weird so I went to look at the stream attribute 
+rules. It turns out that all of the abstract type rules have to do with 
+function 'Input, so those don't apply here.
+
+But stream attributes do have 13.13.2(38.1/4):
+
+The subprogram name given in such an attribute_definition_clause or 
+aspect_specification shall statically denote a subprogram that is not an 
+abstract subprogram. Furthermore, if a specific stream-oriented attribute is
+specified for an interface type, the subprogram name given in the 
+attribute_definition_clause or aspect_specification shall statically denote a
+null procedure.
+
+You don't have such a rule, but it seems needed. (We don't want to be calling 
+abstract subprograms!) The second part seems to come from the fact that the 
+only primitive concrete operation of an interface is a null procedure. (I 
+didn't look up the exact reason for it, it could have come from any one of
+6 AIs - streams were a mess years ago!)
+
+***************************************************************

Questions? Ask the ACAA Technical Agent