Version 1.1 of ais/ai-00137.txt

Unformatted version of ais/ai-00137.txt version 1.1
Other versions for file ais/ai-00137.txt

!standard 13.01 (10)          96-07-23 AI95-00137/01
!class binding interpretation 96-05-07
!status WG9 approved 96-12-07
!status ARG approved 6-0-2 96-06-17
!status work item 96-05-08
!status received 96-05-07
!priority High
!difficulty Medium
!subject Attribute definition clause for Stream Attributes
!summary 96-05-08
13.1(10) says:
10 For an untagged derived type, no type-related representation items are allowed if the parent type is a by-reference type, or has any user-defined primitive subprograms.
This rule does not apply to an attribute_definition_clause for one of the stream-oriented attributes Read, Write, Input, and Output.
!question 96-05-08
13.1(10) seems to forbid the following example:
with Ada.Streams; use Ada.Streams; generic type T is private; package Attr_Rep is type NT is new T; procedure Attribute_Write( Stream : access Root_Stream_Type'Class; Item : in NT); for NT'Write use Attribute_Write; -- Illegal? (No.) end Attr_Rep;
!recommendation 96-05-08
(See summary.)
!wording 96-05-08
!discussion 96-05-08
The intent of 13.1(10) is to forbid two types from having different representation in certain cases. However, the stream-oriented attributes, although they are formally defined to be "representation attributes", do not actually affect the representation of the type. Therefore, there is no need for 13.1(10) to apply to these attributes. Furthermore, as the example illustrates, applying the rule to these attributes would seriously hinder their usefulness.
!appendix

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!from Anthony Gargaro 96-04-28
!keywords 
!reference 96-5519.a Anthony Gargaro  96-4-28>>
!discussion stream attributes, representation items

A consequence of specifying attribute definition clauses for the stream
attributes is that the restrictions associated with representation items
hamper the use of stream attributes. For example, the following idiom is
illegal by 13.1(11).

with Ada.Streams; use Ada.Streams;
generic
  type T is private;
package Attr_Rep is
  type NT is new T;
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT);
  -- Illegal use of attribute definition clause
  for NT'Write use Attribute_Write;
end Attr_Rep;
package body Attr_Rep is
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT) is
  begin
    -- Save type information for dispatching Write and then call 
    T'Write(Stream, T(Item));
  end Attribute_Write;
end Attr_Rep;

Since allowing such idioms facilitates reading/writing streams that are
architecture neutral, consideration should be given to relaxing the
application of 13.1(10,11) to representation-independent attributes.

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

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!keywords stream attributes, representation items
!reference 96-5519.a Anthony Gargaro  96-4-28
!keywords stream attributes, representation items
!from Norman Cohen 96-04-29
!reference 96-5521.a Norman H. Cohen 96-4-29>>
!discussion

Interestingly, 13.1(11) does not prohibit the following workaround:

with Ada.Streams; use Ada.Streams;
generic
  type T is private;
package Attr_Rep is
  type NT is
     record
        Only_Component: T;
     end record;
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT);
  for NT'Write use Attribute_Write;
end Attr_Rep;
package body Attr_Rep is
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT) is
  begin
    -- Save type information for dispatching Write and then call
    T'Write(Stream, Item.Only_Component);
  end Attribute_Write;
end Attr_Rep;

Of course this is a nuisance:  NT doesn't inherit T's operations, so one
always has to invoke Op(X.Only_Component) instead of Op(X).  One can
define corresponding operations for type NT manually, but there is no way
to allow direct conversions between descendents of NT and types that are
truly in the derivation class for T.  (One wishes to use NT rather than T
in constructing new types, so that the 'Write for the new type invokes
NT'Write.)

On the one hand, the existence of such a loophole indicates that there is
no fundamental problem with the relaxation Anthony suggests.  On the
other hand, the existence of the loophole may make resolution of the
problem a little less of an emergency.

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

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!keywords stream attributes, representation items
!reference 96-5519.a Anthony Gargaro  96-4-28
!keywords stream attributes, representation items
!reference 96-5521.a Norman H. Cohen 96-4-29
!from Bob Duff
!reference 96-5542.a Robert A Duff 96-5-8>>
!discussion

Norm says:

> Interestingly, 13.1(11) does not prohibit the following workaround:
> [workaround involving wrapping the type in a record]

Right.  Another workaround is to simply make the thing a tagged type,
since 13.1(11) applies only to untagged types.

- Bob


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

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!reference 96-5519.a Anthony Gargaro  96-4-28
!reference 96-5521.a Norman H. Cohen 96-4-29
!reference 96-5542.a Robert A Duff 96-5-8
!from Anthony Gargaro 96-05-10
!reference 96-5546.a Anthony 96-5-10>>
!discussion

>>Norm says:

>> Interestingly, 13.1(11) does not prohibit the following workaround:
>> [workaround involving wrapping the type in a record]

to which Bob replied:

>Right.  Another workaround is to simply make the thing a tagged type,
>since 13.1(11) applies only to untagged types.

In the context of the application where this issue was raised both of these 
options were considered. Unfortunately, neither seems satisfactory since the 
useability of the abstraction which is presented to the programmer is 
compromised. This is because the idiom requires the incremental composition of 
types to allow arbitrary user-defined types to be associated with "architecture 
neutral" stream attributes.

In the case of wrapping the type (which is used at the moment), there is a 
useability penalty. The programmer must be aware of the wrapper name when 
referencing subcomponents of the type and this may become onerous if the 
composite type contains other composite types.



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

Questions? Ask the ACAA Technical Agent