From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!mnetor!tmsoft!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!uunet!mcsun!cernvax!chx400!chx400!sicsun!disuns2!elcgl.epfl.ch!madmats From: madmats@elcgl.epfl.ch Newsgroups: comp.lang.ada Subject: Re: layered packages Message-ID: <1991Feb16.143244.1@elcgl.epfl.ch> Date: 16 Feb 91 13:32:44 GMT References: <44213@ut-emx.uucp> Sender: news@disuns2.epfl.ch Organization: Ecole Polytechnique Federale de Lausanne List-Id: In article <44213@ut-emx.uucp>, hasan@emx.utexas.edu (David A. Hasan) writes: > My question is best asked in the context of an example. Suppose > I have the following package which exports a primitive > ADT and some fundamental operations on the ADT: > > GENERIC > TYPE item IS PRIVATE; > TYPE coord IS (<>); > PACKAGE grid IS > TYPE adt IS PRIVATE; > FUNCTION fetch( from_adt : IN adt; > at_y, at_x : IN coord ) RETURN item; > PROCEDURE store( the_item : IN item; > in_adt : IN OUT adt; > at_y, at_x : IN coord ); > PRIVATE > TYPE adt IS ...whatever...; > END grid; > > "grid.adt" could be used for a number of things, but suppose I want > to build a numerical matrix layer on top. Here's my attempt: > > WITH grid; > GENERIC > TYPE scalar IS PRIVATE; > -- WITH "+", "-" etc... > TYPE index IS (<>); > PACKAGE matrix IS > TYPE adt IS PRIVATE; > FUNCTION fetch( from_adt : IN adt; *** > at_row, at_col : IN index ) RETURN scalar; > PROCEDURE store( in_adt : IN OUT adt; > at_row, at_col : IN index ); -- I guess you meant: *** PROCEDURE store( the_item : in Scalar; *** in_adt : IN OUT adt; at_row, at_col : IN index ); > FUNCTION invert( the_matrix : IN adt ) RETURN adt; > -- etc... > PRIVATE > PACKAGE low_level IS NEW grid(scalar,index); > TYPE adt IS NEW low_level.adt; > -- the derived type comes complete with of low_level > -- subprograms "fetch" and "store" No, it does not because the derived subprograms fetch and sotre are hidden by the ones declared above (see *** marks), because they have the same parameter and result type profile. If you want to call the original subprograms, you have to use type conversions in order to call the subprograms that are declared in the package instance low_level (see below). > END matrix; > > How can one implement "matrix.fetch" and "matrix.store" so that > they are the *same* as the derived subprograms fetch and store visible at the > end of the PRIVATE part of the package (i.e., how do I reexport them)? > For that matter, how can they be implemented to *call* the derived subprograms? package body Matrix is FUNCTION fetch( from_adt : IN adt; at_row, at_col : IN index ) RETURN scalar is begin return Low_Level.Fetch(From_ADT => Low_Level.ADT(From_ADT), -- type conversion At_X => At_Row, At_Y => At_Col); end fetch; PROCEDURE store( the_item : in Scalar; in_adt : IN OUT adt; at_row, at_col : IN index ) is begin Low_Level.Store(The_Item, In_ADT => Low_Level.ADT(In_ADT), At_X => At_Row, At_Y => At_Col); end store; end Matrix; I think all this is awful because if you reuse a lower level ADT for implementing another one, operations that you redefine with the same name are not written in the same way as the ones that are renamed. The problem even becomes worse when the ADTs export generics (iterators for example). At this point, please let me know if you still think Ada does not need a *real* mechanism for inheritance. > > Should I perhaps use a SUBTYPE instead of a derived type? No you shouldn't because you can't: full declarations of private types must be new types, distinct from all others; in particular, they can't be subtypes. Mats Weber