comp.lang.ada
 help / color / mirror / Atom feed
* Using Generic Pasckages
@ 2020-04-09  8:40 ldries46
  2020-04-09  8:57 ` Dmitry A. Kazakov
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: ldries46 @ 2020-04-09  8:40 UTC (permalink / raw)


I have created some generic packages. tese are packages that only do the 
same thing but with other types. Till now I did only need these packages 
without interaction with between packages using the same type. I just 
can declare them:
Package AA is new BB(type); then calling them as
A := AA.Get_Value;
No other declaration seemed to be neccesary .

Now I have the following situation:
Package AA is new BB(integer);
Package CC is new BB(integer);
and a case where I have several statements using Package AA in one 
condition and CC the other case.
I want  to do that by using:
if D then EE := AA; else EE := CC; end if;
But I cannot find in the documentation  how the declaration of EE should 
be made.

Of course there is the possibility to create the same progrram without 
using EE but that is far less readable and thus creating more possible 
errors.

If I have to do this without the generic packages I already have the 
program alse will be less readable.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-09  8:40 Using Generic Pasckages ldries46
@ 2020-04-09  8:57 ` Dmitry A. Kazakov
  2020-04-09 10:05   ` ldries46
  2020-04-09 15:38 ` AdaMagica
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2020-04-09  8:57 UTC (permalink / raw)


On 2020-04-09 10:40, ldries46 wrote:
> I have created some generic packages. tese are packages that only do the 
> same thing but with other types. Till now I did only need these packages 
> without interaction with between packages using the same type. I just 
> can declare them:
> Package AA is new BB(type); then calling them as
> A := AA.Get_Value;
> No other declaration seemed to be neccesary .
> 
> Now I have the following situation:
> Package AA is new BB(integer);
> Package CC is new BB(integer);
> and a case where I have several statements using Package AA in one 
> condition and CC the other case.
> I want  to do that by using:
> if D then EE := AA; else EE := CC; end if;
> But I cannot find in the documentation  how the declaration of EE should 
> be made.
> 
> Of course there is the possibility to create the same progrram without 
> using EE but that is far less readable and thus creating more possible 
> errors.
> 
> If I have to do this without the generic packages I already have the 
> program alse will be less readable.

What you are observing is the advantages of dynamic polymorphism (tagged 
types) over the static one (generics).

Already the name static hints that you cannot select a polymorphic 
implementation (AA or CC) using some non-static (dynamic) expression D.

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-09  8:57 ` Dmitry A. Kazakov
@ 2020-04-09 10:05   ` ldries46
  2020-04-09 11:23     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: ldries46 @ 2020-04-09 10:05 UTC (permalink / raw)
  To: Dmitry A. Kazakov

Op 9-4-2020 om 10:57 schreef Dmitry A. Kazakov:
> On 2020-04-09 10:40, ldries46 wrote:
>> I have created some generic packages. tese are packages that only do 
>> the same thing but with other types. Till now I did only need these 
>> packages without interaction with between packages using the same 
>> type. I just can declare them:
>> Package AA is new BB(type); then calling them as
>> A := AA.Get_Value;
>> No other declaration seemed to be neccesary .
>>
>> Now I have the following situation:
>> Package AA is new BB(integer);
>> Package CC is new BB(integer);
>> and a case where I have several statements using Package AA in one 
>> condition and CC the other case.
>> I want  to do that by using:
>> if D then EE := AA; else EE := CC; end if;
>> But I cannot find in the documentation  how the declaration of EE 
>> should be made.
>>
>> Of course there is the possibility to create the same progrram 
>> without using EE but that is far less readable and thus creating more 
>> possible errors.
>>
>> If I have to do this without the generic packages I already have the 
>> program alse will be less readable.
>
> What you are observing is the advantages of dynamic polymorphism 
> (tagged types) over the static one (generics).
>
> Already the name static hints that you cannot select a polymorphic 
> implementation (AA or CC) using some non-static (dynamic) expression D.
>
I am using Generic because in the program the same routines should be 
possible for several different types, but now I have also a situation 
where two instantiations of the same type should be used under some 
conditions. For instance in a instantiation of a buffer of 
Unbounded.String's depending on the condition one of two should be used, 
but the buffer should also be used for another type

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-09 10:05   ` ldries46
@ 2020-04-09 11:23     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2020-04-09 11:23 UTC (permalink / raw)


On 2020-04-09 12:05, ldries46 wrote:
> Op 9-4-2020 om 10:57 schreef Dmitry A. Kazakov:
>> On 2020-04-09 10:40, ldries46 wrote:
>>> I have created some generic packages. tese are packages that only do 
>>> the same thing but with other types. Till now I did only need these 
>>> packages without interaction with between packages using the same 
>>> type. I just can declare them:
>>> Package AA is new BB(type); then calling them as
>>> A := AA.Get_Value;
>>> No other declaration seemed to be neccesary .
>>>
>>> Now I have the following situation:
>>> Package AA is new BB(integer);
>>> Package CC is new BB(integer);
>>> and a case where I have several statements using Package AA in one 
>>> condition and CC the other case.
>>> I want  to do that by using:
>>> if D then EE := AA; else EE := CC; end if;
>>> But I cannot find in the documentation  how the declaration of EE 
>>> should be made.
>>>
>>> Of course there is the possibility to create the same progrram 
>>> without using EE but that is far less readable and thus creating more 
>>> possible errors.
>>>
>>> If I have to do this without the generic packages I already have the 
>>> program alse will be less readable.
>>
>> What you are observing is the advantages of dynamic polymorphism 
>> (tagged types) over the static one (generics).
>>
>> Already the name static hints that you cannot select a polymorphic 
>> implementation (AA or CC) using some non-static (dynamic) expression D.
>>
> I am using Generic because in the program the same routines should be 
> possible for several different types, but now I have also a situation 
> where two instantiations of the same type should be used under some 
> conditions. For instance in a instantiation of a buffer of 
> Unbounded.String's depending on the condition one of two should be used, 
> but the buffer should also be used for another type

A solution, without going into what to change in Ada, is to make an 
interface and put data, e.g. Unbounded_String into an implementation of. 
BB will work on the interface's class.

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-09  8:40 Using Generic Pasckages ldries46
  2020-04-09  8:57 ` Dmitry A. Kazakov
@ 2020-04-09 15:38 ` AdaMagica
  2020-04-09 18:23 ` Simon Wright
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: AdaMagica @ 2020-04-09 15:38 UTC (permalink / raw)


Am Donnerstag, 9. April 2020 10:40:11 UTC+2 schrieb ldries46:
> I have created some generic packages. tese are packages that only do the 
> same thing but with other types. Till now I did only need these packages 
> without interaction with between packages using the same type. I just 
> can declare them:
> Package AA is new BB(type); then calling them as
> A := AA.Get_Value;
> No other declaration seemed to be neccesary .
> 
> Now I have the following situation:
> Package AA is new BB(integer);
> Package CC is new BB(integer);
> and a case where I have several statements using Package AA in one 
> condition and CC the other case.
> I want  to do that by using:
> if D then EE := AA; else EE := CC; end if;

You cannot assign packages.

Why not:

if D then AA.Get_Value; else CC.Get_Value; end if;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-09  8:40 Using Generic Pasckages ldries46
  2020-04-09  8:57 ` Dmitry A. Kazakov
  2020-04-09 15:38 ` AdaMagica
@ 2020-04-09 18:23 ` Simon Wright
  2020-04-09 20:45 ` Jere
  2020-04-10 16:34 ` Stephen Leake
  4 siblings, 0 replies; 10+ messages in thread
From: Simon Wright @ 2020-04-09 18:23 UTC (permalink / raw)


ldries46 <bertus.dries@planet.nl> writes:

> Now I have the following situation:
> Package AA is new BB(integer);
> Package CC is new BB(integer);
> and a case where I have several statements using Package AA in one
> condition and CC the other case.
> I want  to do that by using:
> if D then EE := AA; else EE := CC; end if;
> But I cannot find in the documentation  how the declaration of EE
> should be made.

Presume you mean

   if D then EE := AA.Get_Value; else EE := CC.Get_Value; end if;

which will work fine as long as Get_Value returns the type that AA, CC
were instantiated with & not some derived tye.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-09  8:40 Using Generic Pasckages ldries46
                   ` (2 preceding siblings ...)
  2020-04-09 18:23 ` Simon Wright
@ 2020-04-09 20:45 ` Jere
  2020-04-10 16:34 ` Stephen Leake
  4 siblings, 0 replies; 10+ messages in thread
From: Jere @ 2020-04-09 20:45 UTC (permalink / raw)


On Thursday, April 9, 2020 at 4:40:11 AM UTC-4, ldries46 wrote:
> I have created some generic packages. tese are packages that only do the 
> same thing but with other types. Till now I did only need these packages 
> without interaction with between packages using the same type. I just 
> can declare them:
> Package AA is new BB(type); then calling them as
> A := AA.Get_Value;
> No other declaration seemed to be neccesary .
> 
> Now I have the following situation:
> Package AA is new BB(integer);
> Package CC is new BB(integer);
> and a case where I have several statements using Package AA in one 
> condition and CC the other case.
> I want  to do that by using:
> if D then EE := AA; else EE := CC; end if;
> But I cannot find in the documentation  how the declaration of EE should 
> be made.
> 
> Of course there is the possibility to create the same progrram without 
> using EE but that is far less readable and thus creating more possible 
> errors.
> 
> If I have to do this without the generic packages I already have the 
> program alse will be less readable.

You've already had suggestions for polymorphism or using if/else 
scaffolding.  For run time decisions like this, if both packages
are using the same types, I would recommend polymorphism.  However
if you prefer to stick with generics, you make the scaffolding a bit
less painful by using another generic.  Assuming your generic BB has
a specification like this:

    generic
        type Some_Type is private;
    package BB is
        procedure Set_Value(V : Some_Type);
        function Get_Value return Some_Type;
    end BB;

You can abstract out all your logic using it with another generic
similar to:

    generic
        with package EE is new BB(Some_Type => Integer);
    procedure Do_Stuff;
    
    procedure Do_Stuff is
    
        V : Integer := 23;
    
    begin
        Put_Line(Integer'Image(EE.Get_Value));
        EE.Set_Value(V);
        Put_Line(Integer'Image(EE.Get_Value));
        
        -- All your other BB logic you want to do

    end Do_Stuff;

then you pair it with the if/else or case structure 
and locally declared blocks:

    Put_Line("Hello, world!");
    AA.Set_Value(10);
    CC.Set_Value(20);
  
    if D then 
        declare
            procedure P is new Do_Stuff(AA);
        begin
            P;
        end;
    else
        declare
            procedure P is new Do_Stuff(CC);
        begin
            P;
        end;
    end if;

It still has some scaffolding, but it is more 
readable then tons of if/else blocks scattered
throughout the code.  If your packages don't 
have to rely on Integer, you can change the 
specification to:

    generic
        with package EE is new BB(<>);
    procedure Do_Stuff;

But if your logic actually does rely on knowing
it is an integer type, you will get compiler errors.

Full compilable example below:

with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
    
    generic
        type Some_Type is private;
    package BB is
        procedure Set_Value(V : Some_Type);
        function Get_Value return Some_Type;
    end BB;
    
    package body BB is
        Value : Some_Type;
        
        procedure Set_Value(V : Some_Type) is
        begin
            Value := V;
        end Set_Value;
        
        function Get_Value return Some_Type is (Value);
    end BB;
    
    package AA is new BB(Integer);
    package CC is new BB(Integer);
    
    generic
        with package EE is new BB(<>);
    procedure Do_Stuff_1;
    
    procedure Do_Stuff_1 is
    
        V : EE.Some_Type := EE.Get_Value;
    
    begin
        EE.Set_Value(V);
    end Do_Stuff_1;
    
    generic
        with package EE is new BB(Some_Type => Integer);
    procedure Do_Stuff_2;
    
    procedure Do_Stuff_2 is
    
        V : Integer := 23;
    
    begin
        Put_Line(Integer'Image(EE.Get_Value));
        EE.Set_Value(V);
        Put_Line(Integer'Image(EE.Get_Value));
    end Do_Stuff_2;
    
    D : Boolean := True;

begin
    Put_Line("Hello, world!");
    AA.Set_Value(10);
    CC.Set_Value(20);
  
    if D then 
        declare
            procedure P is new Do_Stuff_2(AA);
        begin
            P;
        end;
    else
        declare
            procedure P is new Do_Stuff_2(CC);
        begin
            P;
        end;
    end if;
  
end Hello;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-09  8:40 Using Generic Pasckages ldries46
                   ` (3 preceding siblings ...)
  2020-04-09 20:45 ` Jere
@ 2020-04-10 16:34 ` Stephen Leake
  2020-04-11 13:16   ` ldries46
  4 siblings, 1 reply; 10+ messages in thread
From: Stephen Leake @ 2020-04-10 16:34 UTC (permalink / raw)


On Thursday, April 9, 2020 at 1:40:11 AM UTC-7, ldries46 wrote:
> I have created some generic packages. tese are packages that only do the 
> same thing but with other types. Till now I did only need these packages 
> without interaction with between packages using the same type. I just 
> can declare them:
> Package AA is new BB(type); then calling them as
> A := AA.Get_Value;
> No other declaration seemed to be neccesary .
> 
> Now I have the following situation:
> Package AA is new BB(integer);
> Package CC is new BB(integer);
> and a case where I have several statements using Package AA in one 
> condition and CC the other case.
> I want  to do that by using:
> if D then EE := AA; else EE := CC; end if;

Why do you have both AA and CC? Clearly they instantiate to the same code. Eliminate one of them.

Unless you've simplified things for this post, in which case you've simplified too much.

-- Stephe

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-10 16:34 ` Stephen Leake
@ 2020-04-11 13:16   ` ldries46
  2020-04-11 14:15     ` Jeffrey R. Carter
  0 siblings, 1 reply; 10+ messages in thread
From: ldries46 @ 2020-04-11 13:16 UTC (permalink / raw)
  To: Stephen Leake

Op 10-4-2020 om 18:34 schreef Stephen Leake:
> On Thursday, April 9, 2020 at 1:40:11 AM UTC-7, ldries46 wrote:
>> I have created some generic packages. tese are packages that only do the
>> same thing but with other types. Till now I did only need these packages
>> without interaction with between packages using the same type. I just
>> can declare them:
>> Package AA is new BB(type); then calling them as
>> A := AA.Get_Value;
>> No other declaration seemed to be neccesary .
>>
>> Now I have the following situation:
>> Package AA is new BB(integer);
>> Package CC is new BB(integer);
>> and a case where I have several statements using Package AA in one
>> condition and CC the other case.
>> I want  to do that by using:
>> if D then EE := AA; else EE := CC; end if;
> Why do you have both AA and CC? Clearly they instantiate to the same code. Eliminate one of them.
>
> Unless you've simplified things for this post, in which case you've simplified too much.
>
> -- Stephe
The problem is that I have two streams of data within my program that 
are almost the same I just have to safe them in two random access 
buffers. These two buffers will be filled with two complete different 
sets of data.
The difference between these data streams is not the program part where 
most of the buffering  is done. That part is identical between the two 
data streams. So I wanted to use the same procedures and functions where 
possible.
I already have a generic package for such a buffer (instantiations can 
be made for all kind of types(f.i integers, unbounded_Strings). Do it is 
logical that I want to use that package with two instantiations for the 
same type.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Using Generic Pasckages
  2020-04-11 13:16   ` ldries46
@ 2020-04-11 14:15     ` Jeffrey R. Carter
  0 siblings, 0 replies; 10+ messages in thread
From: Jeffrey R. Carter @ 2020-04-11 14:15 UTC (permalink / raw)


On 4/11/20 3:16 PM, ldries46 wrote:
> I already have a generic package for such a buffer (instantiations can be made 
> for all kind of types(f.i integers, unbounded_Strings). Do it is logical that I 
> want to use that package with two instantiations for the same type.

If your generic requires 2 instantiations to have 2 buffers, then it's an 
Abstract State Machine (ASM). Another approach is an Abstract Data Type (ADT). 
With an ADT you'd have a single instantiation and 2 objects of the ADT's type.

-- 
Jeff Carter
"Frankie Wolf, wanted by Federal authorities for
dancing with a mailman."
Take the Money and Run
143

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-04-11 14:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-09  8:40 Using Generic Pasckages ldries46
2020-04-09  8:57 ` Dmitry A. Kazakov
2020-04-09 10:05   ` ldries46
2020-04-09 11:23     ` Dmitry A. Kazakov
2020-04-09 15:38 ` AdaMagica
2020-04-09 18:23 ` Simon Wright
2020-04-09 20:45 ` Jere
2020-04-10 16:34 ` Stephen Leake
2020-04-11 13:16   ` ldries46
2020-04-11 14:15     ` Jeffrey R. Carter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox