[comp.lang.ada] Record rep specs for private components

joe@petsd.UUCP (Joe Orost) (06/10/89)

We're having a discussion within the posix-ada group about the legality of
record rep-specs for record components of a private type.  I want to find
out what current compilers accept.  Can a few of you try this on various Ada 
compilers (Don't bother if you have VERDIX or SYSTEAM; I tried those):

   package a is
      type aa is private;
   private
      type aa is range 0..1000;
   end a;

   with a;
   package b is
      type bb is record
         bbb : a.aa;
      end record;
      for bb use record
        at mod 2;
        bbb at 0 range 0..15;       --Legal?
      end record;
      x : bb;
   end b;

Please send mail.  I will summarize to the net.

				regards,
				joe

--

 Full-Name:  Joseph M. Orost
 UUCP:       rutgers!petsd!joe
 ARPA:	     petsd!joe@RUTGERS.EDU, joe@petsd.ccur.com
 Phone:      (201) 758-7284
 US Mail:    MS 313; Concurrent Computer Corporation; 106 Apple St
             Tinton Falls, NJ 07724

eberard@ajpo.sei.cmu.edu (Edward Berard) (06/18/89)

I have a problem with the following:

>   package a is
>      type aa is private;
>   private
>      type aa is range 0..1000;
>   end a;
>
>   with a;
>   package b is
>      type bb is record
>         bbb : a.aa;
>      end record;
>      for bb use record
>        at mod 2;
>        bbb at 0 range 0..15;       --Legal?
>      end record;
>      x : bb;
>   end b;

If type a.aa is private, then its underlying implementation should be
unknown outside of package a. This means that it should be impossible
for another program unit to specify how much space an instance of this
type should take up. [Of course, package a could supply operations
which could provide alternative representations of known sizes, and
these could be used in other program units.]

In short, if the rep spec is legal Ada, it should not be, and should
be fixed in Ada 9X.

				-- Ed Berard
				   (301) 353-9652

joe@petsd.UUCP (Joe Orost) (06/20/89)

In article <523@ajpo.sei.cmu.edu> eberard@ajpo.UUCP writes:
>If type a.aa is private, then its underlying implementation should be
>unknown outside of package a. This means that it should be impossible
>for another program unit to specify how much space an instance of this
>type should take up. [Of course, package a could supply operations
>which could provide alternative representations of known sizes, and
>these could be used in other program units.]
>
>In short, if the rep spec is legal Ada, it should not be, and should
>be fixed in Ada 9X.

According to AI-00551/02 (DRAFT):

"If a component type is a private type, the size allowed in a component
clause for the type is determined by applying the above rules to the full
declaration of the private type."

I agree.

				regards,
				joe

--

 Full-Name:  Joseph M. Orost
 UUCP:       rutgers!petsd!joe
 ARPA:	     petsd!joe@RUTGERS.EDU, joe@PETSD.CCUR.COM
 Phone:      (201) 758-7284
 US Mail:    MS 322; Concurrent Computer Corporation; 106 Apple St
             Tinton Falls, NJ 07724

Goodenough@sei.cmu.edu (06/24/89)

In article Re: Record rep specs for private components of 20 Jun 89 13:06:12
GMT joe@petsd.UUCP (Joseph M. Orost) writes:

>According to AI-00551/02 (DRAFT):
>
>"If a component type is a private type, the size allowed in a component
>clause for the type is determined by applying the above rules to the full
>declaration of the private type."

AI-00551 is currently up to version 05, and is still under consideration by
the ARG.  AI-00550 briefly justifies why rep clause support is being required
for certain private types, namely, that if such clauses are not supported for
private types, the effect could be to discourage the use of private types,
since the decision to make a type private would then be equivalent to saying
that objects of the type never need to be positioned explicitly by component
clauses.  As a matter of language design, you don't want programmers to be
concerned about such effects when deciding whether to make a type private.
This would link privateness and rep clause issues in an undesirable way.

Ed Berard says that the underlying implementation of a private type should
not be known outside its parent package, and goes on to say:

"This means that it should be impossible for another program unit to specify
how much space an instance of this type should take up." 

But the point of a private type is not that its implementation is unknown --
it is that a program can't exploit that knowledge in unsafe ways.  To ensure
this, the language limits operations on objects of a private type to those
that are declared explicitly in the type's package.  The type's representation
is hidden in the sense that no representation-dependent operations are
visible.  This means, in general, that the logical properties of a program
are unchanged if the private type's representation is changed later.  Of
course, the effect of a program is similarly unchanged if a component clause
is given for a component having a private type, since the component clause
does not change the set of values allowed for the component, or the effect of
operations on the component.  So the ability to give a component clause is
quite consistent with the notion of a private type.

Of course, if a component clause is given for a private type and the private
type's full declaration is changed later, the component clause might no longer
be accepted (e.g., the component might require more space).  But such an
invalid component clause will be detected when the unit containing the rep
clause is recompiled, so there is no violation of safety.

In short, it would be a mistake to forbid the application of a component
clause to a component just because the component has a private type.

John B. Goodenough					Goodenough@sei.cmu.edu
Software Engineering Institute				412-268-6391

eberard@ajpo.sei.cmu.edu (Edward Berard) (06/24/89)

In article <3560@fy.sei.cmu.edu>, Goodenough@sei.cmu.edu writes:
> 
> AI-00551 is currently up to version 05, and is still under consideration by
> the ARG.  AI-00550 briefly justifies why rep clause support is being required
> for certain private types, namely, that if such clauses are not supported for
> private types, the effect could be to discourage the use of private types,
> since the decision to make a type private would then be equivalent to saying
> that objects of the type never need to be positioned explicitly by component
> clauses.  As a matter of language design, you don't want programmers to be
> concerned about such effects when deciding whether to make a type private.
> This would link privateness and rep clause issues in an undesirable way.
> 

I am strongly in favor of private types. Indeed, it is through the
information hiding provided by private types that module (and object)
coupling is reduced. I also understand the need for "rep specs."
However, the purpose of rep specs often seems at odds with the
purpose of private types, i.e., the very purpose of rep specs is to
explicitly define the underlying implementations.

> Ed Berard says that the underlying implementation of a private type should
> not be known outside its parent package, and goes on to say:
> 
> "This means that it should be impossible for another program unit to specify
> how much space an instance of this type should take up." 
> 
> But the point of a private type is not that its implementation is unknown --
> it is that a program can't exploit that knowledge in unsafe ways.  To ensure
> this, the language limits operations on objects of a private type to those
> that are declared explicitly in the type's package. The type's representation
> is hidden in the sense that no representation-dependent operations are
> visible.  This means, in general, that the logical properties of a program
> are unchanged if the private type's representation is changed later.  Of
> course, the effect of a program is similarly unchanged if a component clause
> is given for a component having a private type, since the component clause
> does not change the set of values allowed for the component, or the effect of
> operations on the component.  So the ability to give a component clause is
> quite consistent with the notion of a private type.
> 
> Of course, if a component clause is given for a private type and the private
> type's full declaration is changed later, the component clause might no
>longer be accepted (e.g., the component might require more space). But such an
> invalid component clause will be detected when the unit containing the rep
> clause is recompiled, so there is no violation of safety.
> 
> In short, it would be a mistake to forbid the application of a component
> clause to a component just because the component has a private type.
> 
> John B. Goodenough

[Before I begin the next discussion, I will admit that there are a few
issues that I do not about. For example, is rep spec support required
for all private types? Is rep spec support required for limited
private types? Is rep spec support limited to scalar private types,
i.e., it is not allowed for composite private types? What about
(limited) private types with discriminants, or private types
implemented using records with variant parts?]

Simply put, I would prefer that private types be very black boxes.
John Goodenough, and others, suggest that there is some benefit to
making some aspects of a private type visible outside of the program
unit in which it is declared, i.e., a "slightly gray" black box. While
I understand the point (and the usefulness), I think the current
situation has two undesirable drawbacks:

	1. A software engineer who is specifying a record layout using
	   both rep specs and private types must refer to the original
	   private type declaration when allowing space for the
	   private type. This requires both time to find the original
	   component, and possibly several tries at allocating the
	   correct amount of space (remember, the private type can be
	   more complex than a simple integer). The software engineer
	   may even allow more space than is necessary.

	2. If the software engineer is required to allow for a large
	   amount of space originally, and a change to the underlying
	   implementation of the private type greatly reduces
	   necessary space, the compiler may not notify the software
	   engineer that less space is needed. If the software
	   engineer is trying to optimize space, this may prove
	   costly.

I propose (what I feel) is a possible solution: size attributes for
private types which can be used in component clauses. One, or more,
attributes could be used to calculate the minimum amount of space
required. This would decrease the need to refer to the program unit in
which the private type was originally declared, and allow the compiler
to allocate the necessary space (provided that the software engineer
made correct use of the attributes).

If these attributes are already in Ada, then no languages changes are
needed. If not, could such attributes be candidates for Ada 9X?

				-- Ed Berard
				   Berard Software Engineering, Inc.
				   18620 Mateney Road
				   Germantown, Maryland 20874
				   Phone: (301) 353-9652

joe@petsd.UUCP (Joe Orost) (07/22/89)

In article <1620@petsd.UUCP> I write:
>We're having a discussion within the posix-ada group about the legality of
>record rep-specs for record components of a private type.  I want to find
>out what current compilers accept.  Can a few of you try this on various Ada 
>compilers (Don't bother if you have VERDIX or SYSTEAM; I tried those):
>
>   package a is
>      type aa is private;
>   private
>      type aa is range 0..1000;
>   end a;
>
>   with a;
>   package b is
>      type bb is record
>         bbb : a.aa;
>      end record;
>      for bb use record
>        at mod 2;
>        bbb at 0 range 0..15;       --Legal?
>      end record;
>      x : bb;
>   end b;
>
Here is the summary:

	Compiler	Legal?
	   V		  Y
	   S		  N
	   D		  Y
	   A		  Y

Looks like compiler S has a problem.

--joe@petsd.ccur.com