Version 1.1 of ai05s/ai05-0184-1.txt

Unformatted version of ai05s/ai05-0184-1.txt version 1.1
Other versions for file ai05s/ai05-0184-1.txt

!standard A.18.17 (0)          09-11-02 AI05-0184-1/01
!standard A.18.18 (0)
!standard A.18.19 (0)
!standard A.18.20 (0)
!standard A.18.21 (0)
!standard A.18.22 (0)
!class amendment 09-11-02
!status work item 09-11-02
!status received 09-11-02
!priority Medium
!difficulty Medium
!subject Compatibility of streaming of containers
!summary
Compatible streaming operations are required for bounded and unbounded containers.
!problem
Changing between bounded and unbounded versions of the container generics should not break programs which use streaming.
!proposal
(See summary.)
!wording
There are 6 places where we define the "Bounded" version of a container. For example,
A.18.17(1/3):
The language-defined generic package Containers.Bounded_Vectors provides a private type Vector and a set of operations. It provides the same operations as the package Containers.Vectors (see A.18.2), with the difference that the maximum storage is bounded.
Similar text exists for Bounded_Doubly_Linked_Lists, Bounded_Hashed_Maps, Bounded_Ordered_Maps, Containers.Bounded_Hashed_Sets, and Bounded_Ordered_Sets.
Add an "Implementation Requirements" section at each of these 6 points which follows the following template:
For every pair of instances I1 and I2 of either of the two generics Containers.Vectors and Containers.Bounded_Vectors (I1 and I2 need not be instances of the same generic), if the two instances meet the following conditions then the output generated by I1.Vector'Output or I1.Vector'Write shall be readable by I2'Vector'Input or I2'Vector'Read, respectively:
- the Element_Type parameters of the two instances are
statically matching subtypes of the same type (note that distinct elaborations of a type declaration result in distinct types); and
- the output generated Element_Type'Output or Element_Type'Write
is readable by Element_Type'Input or Element_Type'Read, respectively (where Element_Type denotes the type of of the two actual Element_Type parameters); and
- the preceding two conditions also hold the Index_Type
parameters of the instances.
The condition which mentions the Index_Type parameters is omitted for the non-vector containers (which have no Index_Type parameter). In that case, the "; and" of the formerly penultimate condition is replaced with a period.
!discussion
13.13.2(54/1) already uses the phrase "shall be readable by", so we can build on that:
For every subtype S of a language-defined nonlimited specific type T, the output generated by S'Output or S'Write shall be readable by S'Input or S'Read, respectively. This rule applies across partitions if the implementation conforms to the Distributed Systems Annex.
This precedent spares us from having to precisely define that phrase.
During discussions in Brest, the possibility was raised that there is some implementation issue in the Vector case having to do with "empty elements" (A.18.2(14/2)) and, for example, the Insert_Space procedure. Note that the list of operations that result is bounded errors if an empty element is encountered does not include any of the stream operations. An implementation might or might not choose to keep track of "emptiness" at runtime, but the streaming issues in either case seem to be the same for the bounded and unbounded versions (note that we are not talking here about the indefinite version). There could be an issue if an implementation chooses to keep track of emptiness in exactly one of the two (i.e. bounded and unbounded) cases; this requirement of streaming compatibility might impact such an implementation. Does this warrant even an AARM note? Perhaps just a mention in passing in the !discussion section of the AI.
Given
procedure Recursive (N : Natural) is type Element is new String (1 .. N); package Inst is new Some_Container (Element, ...); begin if N /= 0 then Recursive (N - 1); end if; ... ; end Recursive;
We must avoid wording which would incorrectly require any sort of compatibility between the streaming attributes of the container type associated with different elaborations of Recursive.Inst. It is asserted that the proposed wording meets this requirement.
!example
(See discussion.)
!ACATS test
!appendix

From: Steve Baird
Sent: Tuesday, October 6, 2009  5:30 PM

I've got the following item on my to-do list from Brest:

   Investigate and possibly create an AI to require that
   streaming work between bounded and unbounded definite
   forms of the same container kind.

We can begin by noting that 13.13.2(54/1) already uses the phrase "shall be
readable by", so we can build on that:

   For every subtype S of a language-defined nonlimited specific type T,
   the output generated by S'Output or S'Write shall be readable by
   S'Input or S'Read, respectively. This rule applies across partitions
   if the implementation conforms to the Distributed Systems Annex.

This existing precedent spares us from having to nail down a precise definition
of that phrase (unless we decide that it doesn't). One can only imagine what
Justice Potter Stewart might have said if asked to consider the question of
stream-wise compatibility:

   I shall not today attempt further to define the kinds of material I
   understand to be embraced within that shorthand description; and
   perhaps I could never succeed in intelligibly doing so.
   But I know it when I see it ...

There are 6 places where we define the "Bounded" version of a container. For
example,

A.18.17(1/3):
   The language-defined generic package Containers.Bounded_Vectors
   provides a private type Vector and a set of operations. It provides
   the same operations as the package Containers.Vectors (see A.18.2),
   with the difference that the maximum storage is bounded.

Similar text exists for Bounded_Doubly_Linked_Lists, Bounded_Hashed_Maps,
Bounded_Ordered_Maps, Containers.Bounded_Hashed_Sets, and Bounded_Ordered_Sets.

We could add an "Implementation Requirements" section at each of these 6 points
containing something like the following:

    Let I1 be any instance of one of the two generics
    Containers.Vectors and Containers.Bounded_Vectors.
    Let I2 also be an instance of either one of those two generics.
    If the the two instances have matching actual parameters,
    then the output generated by I1.Vector'Output or I1.Vector'Write
    shall be readable by I2'Vector'Input or I2'Vector'Read, respectively.

  AARM note:
    The term "matching" as used here is intended to be consistent
    with the use in 12.6 - two subtypes match if they are statically
    matching subtypes and other parameters match if they statically
    denote the same entity.

    This requirement only applies if the output generated by
    the Output or Write attribute of the Element type is readable
    by the Input or Read attribute of the Element type, respectively.
    Likewise for the streaming attributes of the Index type.

====

Details:

   During discussions in Brest, the possibility was raised that there
   is some implementation issue in the Vector case having to do with
   "empty elements" (A.18.2(14/2)) and, for example, the Insert_Space
   procedure. Note that the list of operations that result in
   bounded errors if an empty element is encountered does not include
   any of the stream operations. An implementation might or might
   not choose to keep track of "emptiness" at runtime, but the
   streaming issues in either case seem to be the same for the
   bounded and unbounded versions (note that we are not talking here
   about the indefinite version). There could be an issue if an
   implementation chooses to keep track of emptiness in exactly
   one of the two (i.e. bounded and unbounded) cases; this
   requirement of streaming compatibility might impact such an
   implementation. Does this warrant even an AARM note? Perhaps just
   a mention in passing in the !discussion section of the AI.

   Does it matter if the two instances are declared at different
   accessibility levels? Is there any need to relax the compatibility
   requirement in that case?

Does this general approach seem like the direction we want to go?
I'd like to reach a consensus (either pro or con) before proceeding further.

****************************************************************

From: Tucker Taft
Sent: Tuesday, October 6, 2009  5:43 PM

Your proposal looks good to me, though the wording "Let I1 be ..." is not our
usual way of introducing names in a description. Usually we say something like
"Given an instance I1 of ..." or "For every instance I1 ...".

For what that's worth...

****************************************************************

From: Steve Baird
Sent: Tuesday, October 6, 2009  5:54 PM

I like the latter form - "For every instance I1", although now that you point it
out, either is an improvement on my initial wording.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, October 6, 2009  7:10 PM

I agree with Tucker. I think that the basic idea is that we want to maximize
interoperability between the bounded and unbounded forms (in order that
switching between them is as painless as possible). But of course we don't want
to go too far with that such that we impose insane implementation requirements
(especially if they reduce the advantages of either form).

What you have sounds right, presuming that you don't uncover any implementation
complexities. (If it was anyone else, I wouldn't worry much, but you are so good
at finding obscure problems that I will not make the mistake of thinking that
this will work in the end.)

I wonder if you could use the existing phrase "supports external streaming" to
describe the cases that must work. I don't think we want to require anything for
element types that include access types (not that it matters a whole lot in this
case).

Humm, that really isn't enough. (If the 'Read and 'Write attributes are
specified and aren't inverses of each other, we are still hosed.) You mention
that in an AARM note, but I think that is more fundamental than a note: I think
you need to work that into the actual requirement somehow. We don't want to be
appearing to require streaming of a vector of type Foo to work when streaming of
Foo itself does not "work"; that would be silly. (I'd rather not be applying
Dewar's rule to newly created text!)

****************************************************************

From: Steve Baird
Sent: Tuesday, October 6, 2009  7:21 PM

You also might want to cover a case I thought of later, where you elaborate the
same instance more than once (e.g., in a recursive subprogram) and we don't want
to require any sort of compatibility between the streaming representations of
the two (albeit statically one) instances.

****************************************************************

From: Robert Dewar
Sent: Tuesday, October 6, 2009  7:55 PM

why not?

can you see any reason in practice why the representations would not be
compatible? If not, then it's just pedantic stuff to say they are not the same.

After all, from a formal RM point of view, when we say

    X : Integer;
    Y : Integer;

there is no requirement that X and Y have the same representation, but in
practice of course they do.

****************************************************************

From: Steve Baird
Sent: Wednesday, October 7, 2009  10:12 AM

I was thinking (although I failed to mention this) of the case where the
recursive subprogram also included the declaration of the element type used to
instantiate the container, as in

     type T is record
       C1, C2 : String (1 .. Some_Parameter);
     end record;

    package I is new Some_Container (T, ...);

****************************************************************

From: Steve Baird
Sent: Monday, November 2, 2009  3:53 PM

As per Randy's request that I finish off my homework from Brest, here are the
results of the ARG's 10/6-10/7 discussion of this topic in something resembling
AI form. Not much new here.

[This is version /01 of this AI - ED]

****************************************************************

From: Randy Brukardt
Sent: Monday, November 2, 2009  6:54 PM

...
> Add an "Implementation Requirements" section at each of these
> 6 points which follows the following template:
>
>     For every pair of instances I1 and I2 of either of the two
>     generics Containers.Vectors and Containers.Bounded_Vectors
>     (I1 and I2 need not be instances of the same generic),
>     if the the two instances meet the the following conditions
>     then the output generated by I1.Vector'Output or I1.Vector'Write
>     shall be readable by I2'Vector'Input or I2'Vector'Read, respectively:
>         - the Element_Type parameters of the two instances are
>           statically matching subtypes of the same type (note that
>           distinct elaborations of a type declaration result in
>           distinct types); and
>         - the output generated Element_Type'Output or Element_Type'Write
>           is readable by Element_Type'Input or Element_Type'Read,
>           respectively (where Element_Type denotes the type of
>           of the two actual Element_Type parameters); and
>         - the preceding two conditions also hold the Index_Type
>           parameters of the instances.
>
> The condition which mentions the Index_Type parameters is omitted for
> the non-vector containers (which have no Index_Type parameter).

Would you not need to have similar wording for the Key_Type parameter of maps??
I would expect that some form of the keys would need to be streamed so that the
hash table/ordering information could be reconstructed (at the least, if the
capacity is changed after the container is streamed in).

****************************************************************

From: Randy Brukardt
Sent: Monday, November 2, 2009  6:56 PM

>     if the the two instances meet the the following conditions

Stuttering here?? A strange fetish for the word "the"? ;-)

I've fixed this in the posted AI.

****************************************************************

Questions? Ask the ACAA Technical Agent