[comp.lang.ada] layering with discriminants

hasan@emx.utexas.edu (David A. Hasan) (03/02/91)

In my struggle to understand how to build layered components
in Ada, I have encountered a problem with discriminants.
Consider the following "low level" generic component:


GENERIC
   TYPE size IS (<>);
PACKAGE g_lowLevel IS
   TYPE adt (i : size) IS PRIVATE;
   -- ...other stuff...
PRIVATE
   TYPE adt (i : size) IS RECORD
    -- ...whatever...
   END RECORD;
END g_lowLevel;


Now, add a layer on top as follows:


WITH g_lowLevel;
GENERIC
   TYPE length IS (<>);
PACKAGE g_highLevel IS
   TYPE adt (i : length) IS PRIVATE;
   -- ...other stuff...
PRIVATE
   PACKAGE low_level IS NEW g_lowLevel(length);
   TYPE adt (i : length) IS NEW low_level.adt(i);   ---!!!
    -- ...whatever...
END g_highLevel;


This package might provide a different set of operations & semantics 
for its adt but implement it exactly as the lower level adt.  That's
the motivation behind what I'm doing: avoid implementing the guts of
the adt over.  This also factors the design process nicely.

My problem revolves around the fact that the DEC compiler rejects
the presence of the discriminant in the full declaration of the adt in
the private part of g_highLevel, since the declaration is not a record.
But the declaration is *derived* from a record.

My conclusion is that it is not legal to derive
types with discriminants from parents with discriminants.  
If this is true, is there anyway to achieve an equivalent effect?
--
 :   David A. Hasan
 :   WRW 402 Univ. of Texas at Austin, Austin TX 78712
 :   internet: hasan@emx.cc.utexas.edu 

holly@python.cis.ohio-state.edu (Joe Hollingsworth) (03/04/91)

In article <44963@ut-emx.uucp> hasan@emx.utexas.edu (David A. Hasan) writes:
...stuff deleted...
>My problem revolves around the fact that the DEC compiler rejects
>the presence of the discriminant in the full declaration of the adt in
>the private part of g_highLevel, since the declaration is not a record.
>But the declaration is *derived* from a record.

>My conclusion is that it is not legal to derive
>types with discriminants from parents with discriminants.  
>If this is true, is there anyway to achieve an equivalent effect?

There's always this nagging problem when the compiler "rejects"
some program that you feed it:

Is the compiler right and this is not legal Ada, or is there a problem
with the compiler?

This question seems to come up frequently when trying things such
as what was described above.  (As for the above, I don't have an
answer.)

Makes one wonder if having two compilers (from different vendors)
"might" help answer the above question.  Probably not.

Joe
holly@cis.ohio-state.edu

eachus@aries.mitre.org (Robert I. Eachus) (03/05/91)

     This looks like another "meaningless restriction" for Ada9X to
clean up, but for now it is real.  Using Verdix, and wrapping the
declaration as below to make it a record, works fine.  This is not the
only case where such a record wrapper is required, I usually run into
it when I want to make the full declaration of a private type a
subtype of another type.  Note that I also got "bit" but not as badly
when I decided to make adt a "real" discriminated record...I would
have to pass String as a generic formal array type if I wanted St to
depend on i.

					Robert I. Eachus

GENERIC
   TYPE size IS (<>);
PACKAGE g_lowLevel IS
   TYPE adt (i : size) IS PRIVATE;
PRIVATE
   TYPE adt (i : size) IS RECORD
     St: String(1..10);
   END RECORD;
END g_lowLevel;

WITH g_lowLevel;
GENERIC
   TYPE length IS (<>);
PACKAGE g_highLevel IS
   TYPE adt (i : length) IS PRIVATE;
PRIVATE
   PACKAGE low_level IS NEW g_lowLevel(length);
   TYPE adt (i : length) IS RECORD
     LL: low_level.adt(i);
   END RECORD;
END g_highLevel;
--

					Robert I. Eachus

     "As far as Saddam Hussein being a great military strategist, he
is neither a strategist, nor is he schooled in the operational arts,
nor is he a tactician, nor is he a general, nor is he as a
soldier...

Other than that he's a great military man.  I want you to know that."
      -- Gen. H. Norman Schwarzkopf, Saudia Arabia, Feb. 27, 1991  

williams@CRC.SKL.DND.CA (Dave Williamson) (03/06/91)

In INFO-ADA Digest 91-39, David A. Hasan writes:

>GENERIC
>    TYPE size is (<>);
>PACKAGE g_lowLevel IS
>    TYPE adt (i : size) IS PRIVATE;

... lines deleted

>GENERIC
>    TYPE length is (<>);
>PACKAGE g_highLevel IS
>    TYPE adt (i : length) IS PRIVATE;
>PRIVATE
>    PACKAGE low_level IS NEW g_lowLevel(length);
>    TYPE adt (i : length) IS NEW low_level.adt(i);
>END g_highLevel;

Refer to LRM 3.7.1(3) - "A discriminant part is only allowed in the type
declaration for a record type, in a private type declaration or an incomplete
type declaration..."

I don't see anything there about derived types.  It appears that your
compiler was correct to reject, but may have led you down the garden path
with its message.

Dave Williamson
Software Kinetics Ltd.
Ottawa Ontario, Canada
williams@crc.skl.dnd.ca

stt@inmet.inmet.com (03/07/91)

In article <44963@ut-emx.uucp> hasan@emx.utexas.edu (David A. Hasan) writes:
 . . .
>My problem revolves around the fact that the DEC compiler rejects
>the presence of the discriminant in the full declaration of the adt in
>the private part of g_highLevel, since the declaration is not a record.
>But the declaration is *derived* from a record.

>My conclusion is that it is not legal to derive
>types with discriminants from parents with discriminants.  
>If this is true, is there anyway to achieve an equivalent effect?

This is true, and it is admittedly annoying.  One way is
to make the private type into a record containing the parent
as a component.  Some compilers are clever enough to share
the space occupied by the component's discriminants for
the enclosing record's discriminants (since they must always
have the same value).

For example:

    type Blah(X : Integer) is private;

private

    type Blah(X : Integer) is record
        Parent : Parent_Type(X);
    end record;

-S. Tucker Taft
Ada 9X Mapping/Revision Team
Intermetrics, Inc.
Cambridge, MA  02138

P.S. This annoyance has been identified as something which
might be fixable in Ada 9X without too much change, perhaps
by allowing:

    type Blah(X : Integer) is new Parent_Type(X);

in the private part which would make Blah be a derivative of 
Parent_Type, but also allow the declaration to 
fulfill "type Blah(X : Integer) is private;"

It is too early to tell whether such a proposal will survive the
9X review process.