Re: generics and records

From: Dmitry A. Kazakov (mailbox_at_dmitry-kazakov.de)
Date: 02/28/05


Date: Mon, 28 Feb 2005 11:07:08 +0100

On 28 Feb 2005 01:00:59 -0800, spambox@volja.net wrote:

> Dmitry A. Kazakov wrote:
>>>> 2. Inheritance from a record type with known components:
>>>>
>>>> type Common_Base is tagged record
>>>> A : Float; -- This will be visible in Foo
>>>> end record;
>>>>
>>>> generic
>>>> type Record_Type is new Common_Base with private;
>>>> package Foo is
>>>> ...
>>>>
>>>> Instantiation:
>>>>
>>>> type My_Record is new Common_Base with record
>>>> ... -- These new components will be inaccessible in Foo!
>>>> end record;
>>>> package My_Foo is new Foo (My_Record);
>
>> You can't do that. Ada has a contract model of generics. That means that
>> Foo in the example above will never directly see the whole record, only its
>> Common_Base part. The primitive operations defined on Common_Base will. So
>> if Foo has to access all record, the only way to do it is to express what
>> Foo should do in terms of primitive operations defined on Common_Base. They
>> can dispatch to the specific operations defined on the actual type.
>> Usually, it is sufficient for all purposes and also is a good OO-ish
>> programming style. But there is no way to write a generic unit working with
>> whatever components of an actual parameter. Ada does not provide abstract
>> record interfaces with enumeration of components and their types at run
>> time. Though you can implement something close to that using map container
>> types instead of record types. Probably this is what you actually need. But
>> again, to work through primitive operations is better.
>
> Yes, I understand. I was too eager to try your solution out, failed and
> phrased my question poorly. I'm perfectly content with a record like
> Common_Base above. But where should its definition be put? It can't go
> into the package specs, where the "generic ..." part belongs. But if
> it's not there, how can it be seen? -- "type Record_Type is new
> Common_Base with private;"
> andrej

You can:

1. put Common_Base in another package and "with/use" that package in the
generic package specification.

package Bar is
   type Common_Base is ...;
end Bar;
----------------------
with Bar; use Bar;
generic
   type Record_Type is new Common_Base with private;
package Foo is
   ...
end Foo;

2. put both Common_Base and Foo in one package:

package Bar is
   type Common_Base is ...;
   generic
      type Record_Type is new Common_Base with private;
   package Foo is
      ...
   end Foo;
end Bar;

3. put Common_Base in the parent package of Foo:

package Bar is
   type Common_Base is ...;
end Bar;
--------------------
generic
   type Record_Type is new Common_Base with private;
package Bar.Foo is
   ...
end Bar.Foo;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


Relevant Pages