comp.lang.ada
 help / color / mirror / Atom feed
* Generic Library Units?
@ 2014-10-12 14:38 hreba
  2014-10-12 15:47 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 12+ messages in thread
From: hreba @ 2014-10-12 14:38 UTC (permalink / raw)


Hi,

I am writing a facility for graphical toolkits named Gui as a generic 
package and GuiGtk as an actual parameter package. As Gui grew I 
splitted it up into Gui and Gui.SimpleGad. More by trial and error than 
by strict reasoning (and with the help of John Barnes' book) I ended up 
with the following package structure:

gui.ads: parent generic package
-------
with GuiGtk;
generic
    with package TK is new GuiGk(<>);
package Gui is
    ...
end Gui;

gui-simplegad.ads: child package for Gui
-----------------
generic
package Gui.SimpleGad is
    ...
end Gui.SimpleGad

guigtk.ads: actual parameter package for Gui
----------
generic
package GuiGtk is
    ...
end GuiGtk;

mainaux.ads: auxiliary package for the main program
-----------
with Gui;
with GuiGtk;
with Gui.SimpleGad;
package MainAux is
    package Toolkit is new GuiGtk;
    package GuiTK is new Gui(Toolkit);
    ...
end MainAux;

test.adb: Main program
----
with MainAux;
procedure Test is
    ...
end Test;

Now my questions are:

1. Is this really the shortest form? (Why can't I contract the 2 lines 
under "package MainAux is" into "package GuiTK is new Gui(GuiTK)"?

2. The generic package file has to depend on a specific actual package?
If one day I decide to use, let's say Qt, then I will have to change the 
respective lines in gui.ads into
    package Toolkit is new GuiQt; ?

3. My actual package GuiGtk has grown considerably, so I want to split 
up that too into parent and child package, adding something like

guigtk-simplegad.ads:
----------------
package GuiGtk.SimpleGad is
   ...
end GuiGtk.SimpleGad;

No attempt to initialize this in MainAux or call it in Test has been 
working so far. Can somebody please give me a hint?
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


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

* Re: Generic Library Units?
  2014-10-12 14:38 Generic Library Units? hreba
@ 2014-10-12 15:47 ` Dmitry A. Kazakov
  2014-10-12 22:39   ` hreba
  0 siblings, 1 reply; 12+ messages in thread
From: Dmitry A. Kazakov @ 2014-10-12 15:47 UTC (permalink / raw)


On Sun, 12 Oct 2014 11:38:16 -0300, hreba wrote:

[...]
> 1. Is this really the shortest form? (Why can't I contract the 2 lines 
> under "package MainAux is" into "package GuiTK is new Gui(GuiTK)"?

Yes. Each generic instance must have a name and be explicitly instantiated.

> 2. The generic package file has to depend on a specific actual package?

If it has a formal package parameter then each its instance depends on a
specific actual package.

> If one day I decide to use, let's say Qt, then I will have to change the 
> respective lines in gui.ads into
>     package Toolkit is new GuiQt; ?

That will not work. It should be an instance of GuiGk if you want to pass
it as the parameter TK.

> 3. My actual package GuiGtk has grown considerably, so I want to split 
> up that too into parent and child package, adding something like

A child of a generic package must be generic. I.e. you should declare it
this way:

generic
package GuiGtk.SimpleGad is

And you will have to instantiate it somewhere.

Generic packages are not suitable for abstraction GUI engines as complex as
GTK or Qt. If you really want to use both GTK and Qt as the back-end, you
should carefully design a set of abstract tagged types in several packages.
GTK and Qt versions will derive from theses types.

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


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

* Re: Generic Library Units?
  2014-10-12 15:47 ` Dmitry A. Kazakov
@ 2014-10-12 22:39   ` hreba
  2014-10-13  7:45     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 12+ messages in thread
From: hreba @ 2014-10-12 22:39 UTC (permalink / raw)


On 10/12/2014 12:47 PM, Dmitry A. Kazakov wrote:
> On Sun, 12 Oct 2014 11:38:16 -0300, hreba wrote:
>
> A child of a generic package must be generic. I.e. you should declare it
> this way:
>
> generic
> package GuiGtk.SimpleGad is
>

Did that. And I added to Gui.ads the line

    with package TKSG is new GuiGtk.SimpleGad;

Now the line in mainaux.ads:

    package GuiTK is new Gui(Toolkit);

which was correct before, is accused:

mainaux.ads:10:04: missing actual "TKSG"
mainaux.ads:10:04: in instantiation of "Gui" declared at gui.ads:13

Adding
    package ToolkitSG is new GuiGtk.SimpleGad;
before that line gets me
mainaux.ads:9:29: invalid prefix in selected component "GuiGtk"

Replacing it with
    package ToolkitSG is new Toolkit.SimpleGad;
turns the error message into
mainaux.ads:9:36: generic child unit "SimpleGad" is not visible

So how do I instantiate that?

> And you will have to instantiate it somewhere.
>
> Generic packages are not suitable for abstraction GUI engines as complex as
> GTK or Qt. If you really want to use both GTK and Qt as the back-end, you
> should carefully design a set of abstract tagged types in several packages.
> GTK and Qt versions will derive from theses types.
>
I don't want to mix different toolkits. I want to have the same API in 
the case I switch to another one later.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

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

* Re: Generic Library Units?
  2014-10-12 22:39   ` hreba
@ 2014-10-13  7:45     ` Dmitry A. Kazakov
  2014-10-15  0:29       ` hreba
  0 siblings, 1 reply; 12+ messages in thread
From: Dmitry A. Kazakov @ 2014-10-13  7:45 UTC (permalink / raw)


On Sun, 12 Oct 2014 19:39:49 -0300, hreba wrote:

> On 10/12/2014 12:47 PM, Dmitry A. Kazakov wrote:
>> On Sun, 12 Oct 2014 11:38:16 -0300, hreba wrote:
>>
>> A child of a generic package must be generic. I.e. you should declare it
>> this way:
>>
>> generic
>> package GuiGtk.SimpleGad is
> 
> Did that. And I added to Gui.ads the line
> 
>     with package TKSG is new GuiGtk.SimpleGad;
> 
> Now the line in mainaux.ads:
> 
>     package GuiTK is new Gui(Toolkit);
> 
> which was correct before, is accused:
> 
> mainaux.ads:10:04: missing actual "TKSG"
> mainaux.ads:10:04: in instantiation of "Gui" declared at gui.ads:13
> 
> Adding
>     package ToolkitSG is new GuiGtk.SimpleGad;
> before that line gets me
> mainaux.ads:9:29: invalid prefix in selected component "GuiGtk"
> 
> Replacing it with
>     package ToolkitSG is new Toolkit.SimpleGad;
> turns the error message into
> mainaux.ads:9:36: generic child unit "SimpleGad" is not visible
> 
> So how do I instantiate that?

with Gui;
with GuiGtk.SimpleGad;
with Gui.SimpleGad;
package MainAux is
    package Toolkit is new GuiGtk;
    package SimpleGad is new Toolkit.SimpleGad;
    package GuiTK is new Gui (Toolkit, SimpleGad);
end MainAux;

>> And you will have to instantiate it somewhere.
>>
>> Generic packages are not suitable for abstraction GUI engines as complex as
>> GTK or Qt. If you really want to use both GTK and Qt as the back-end, you
>> should carefully design a set of abstract tagged types in several packages.
>> GTK and Qt versions will derive from theses types.
>>
> I don't want to mix different toolkits. I want to have the same API in 
> the case I switch to another one later.

It does not matter. You have to design these "same API" in one way or
another. Doing this in the form of generic packages, when API's basic
operations are formal generic subprograms and the rest is implemented in
these terms is extremely tedious for anything more complex than trivial
teaching examples.

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

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

* Re: Generic Library Units?
  2014-10-13  7:45     ` Dmitry A. Kazakov
@ 2014-10-15  0:29       ` hreba
  2014-10-15  7:21         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 12+ messages in thread
From: hreba @ 2014-10-15  0:29 UTC (permalink / raw)


On 10/13/2014 04:45 AM, Dmitry A. Kazakov wrote:
>
> with Gui;
> with GuiGtk.SimpleGad;
> with Gui.SimpleGad;
> package MainAux is
>      package Toolkit is new GuiGtk;
>      package SimpleGad is new Toolkit.SimpleGad;
>      package GuiTK is new Gui (Toolkit, SimpleGad);
> end MainAux;
>
Ok, did that too, and the error message disappeared.

Now in the package body of Gui.SimpleGad I have

    function Get (gad: BoolGadget) return boolean is
    begin
       return TKSG.GetBool (gad.widget.all);
    end Get;

and get the error message

gui-simplegad.adb:78:39: expected type "GuiGtk.GadWidgets" defined at 
guigtk.ads:38
gui-simplegad.adb:78:39: found type "TK.GadWidgets" defined at 
guigtk.ads:38, instance at gui.ads:10

So the compiler isn't aware that GuiGtk is the actual value to the 
formal package TK. How do I tell him?

( The Gui package header is

    generic
       with package TK is new GuiGtk(<>);	-- this is gui.ads:10
       with package TKSG is new GuiGtk.SimpleGad;
    package Gui is
    ...
)

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

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

* Re: Generic Library Units?
  2014-10-15  0:29       ` hreba
@ 2014-10-15  7:21         ` Dmitry A. Kazakov
  2014-10-16  1:21           ` hreba
  2014-10-16 10:36           ` AdaMagica
  0 siblings, 2 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2014-10-15  7:21 UTC (permalink / raw)


On Tue, 14 Oct 2014 21:29:16 -0300, hreba wrote:

> On 10/13/2014 04:45 AM, Dmitry A. Kazakov wrote:
>>
>> with Gui;
>> with GuiGtk.SimpleGad;
>> with Gui.SimpleGad;
>> package MainAux is
>>      package Toolkit is new GuiGtk;
>>      package SimpleGad is new Toolkit.SimpleGad;
>>      package GuiTK is new Gui (Toolkit, SimpleGad);
>> end MainAux;
>>
> Ok, did that too, and the error message disappeared.
> 
> Now in the package body of Gui.SimpleGad I have
> 
>     function Get (gad: BoolGadget) return boolean is
>     begin
>        return TKSG.GetBool (gad.widget.all);
>     end Get;
> 
> and get the error message
> 
> gui-simplegad.adb:78:39: expected type "GuiGtk.GadWidgets" defined at 
> guigtk.ads:38
> gui-simplegad.adb:78:39: found type "TK.GadWidgets" defined at 
> guigtk.ads:38, instance at gui.ads:10
> 
> So the compiler isn't aware that GuiGtk is the actual value to the 
> formal package TK. How do I tell him?

You can't. GuiGtk is a generic package. It cannot be actual of anything.
Actuals are *real* things. E.g. an instance of a generic package can be
actual of a formal package.

> ( The Gui package header is
> 
>     generic
>        with package TK is new GuiGtk(<>);	-- this is gui.ads:10
>        with package TKSG is new GuiGtk.SimpleGad;
>     package Gui is
>     ...
> )

Which has nothing to do with GuiGtk and GuiGtk.SimpleGad. Generic packages
know nothing about any instances of. That is the basic idea of being
"generic".

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


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

* Re: Generic Library Units?
  2014-10-15  7:21         ` Dmitry A. Kazakov
@ 2014-10-16  1:21           ` hreba
  2014-10-16  7:04             ` Dmitry A. Kazakov
  2014-10-16  7:54             ` Simon Wright
  2014-10-16 10:36           ` AdaMagica
  1 sibling, 2 replies; 12+ messages in thread
From: hreba @ 2014-10-16  1:21 UTC (permalink / raw)


On 10/15/2014 04:21 AM, Dmitry A. Kazakov wrote:
> On Tue, 14 Oct 2014 21:29:16 -0300, hreba wrote:
>
>> On 10/13/2014 04:45 AM, Dmitry A. Kazakov wrote:
>>>
>>> with Gui;
>>> with GuiGtk.SimpleGad;
>>> with Gui.SimpleGad;
>>> package MainAux is
>>>       package Toolkit is new GuiGtk;
>>>       package SimpleGad is new Toolkit.SimpleGad;
>>>       package GuiTK is new Gui (Toolkit, SimpleGad);
>>> end MainAux;
>>>
>> Ok, did that too, and the error message disappeared.
>>
>> Now in the package body of Gui.SimpleGad I have
>>
>>      function Get (gad: BoolGadget) return boolean is
>>      begin
>>         return TKSG.GetBool (gad.widget.all);
>>      end Get;
>>
>> and get the error message
>>
>> gui-simplegad.adb:78:39: expected type "GuiGtk.GadWidgets" defined at
>> guigtk.ads:38
>> gui-simplegad.adb:78:39: found type "TK.GadWidgets" defined at
>> guigtk.ads:38, instance at gui.ads:10
>>
>> So the compiler isn't aware that GuiGtk is the actual value to the
>> formal package TK. How do I tell him?
>
> You can't. GuiGtk is a generic package. It cannot be actual of anything.
> Actuals are *real* things. E.g. an instance of a generic package can be
> actual of a formal package.
>
>> ( The Gui package header is
>>
>>      generic
>>         with package TK is new GuiGtk(<>);	-- this is gui.ads:10
>>         with package TKSG is new GuiGtk.SimpleGad;
>>      package Gui is
>>      ...
>> )
>
> Which has nothing to do with GuiGtk and GuiGtk.SimpleGad. Generic packages
> know nothing about any instances of. That is the basic idea of being
> "generic".
>

Basically I only need type and subprogram parameters for my generic 
package Gui (and Gui.SimpleGad) package.
As I have dozens of subprogram parameters, I packed them (together with 
the types) into a package parameter GuiGtk and it worked. It didn't work 
anymore when I outsourced part of GuiGtk into GuiGtk.SimpleGad.

 From what you say I understand that there is no cure, so I will stick 
to a GuiGtk without a child package.

Thanks for the hints.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


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

* Re: Generic Library Units?
  2014-10-16  1:21           ` hreba
@ 2014-10-16  7:04             ` Dmitry A. Kazakov
  2014-10-16  7:54             ` Simon Wright
  1 sibling, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2014-10-16  7:04 UTC (permalink / raw)


On Wed, 15 Oct 2014 22:21:30 -0300, hreba wrote:

> Basically I only need type and subprogram parameters for my generic 
> package Gui (and Gui.SimpleGad) package.
> As I have dozens of subprogram parameters, I packed them (together with 
> the types) into a package parameter GuiGtk and it worked. It didn't work 
> anymore when I outsourced part of GuiGtk into GuiGtk.SimpleGad.
> 
>  From what you say I understand that there is no cure, so I will stick 
> to a GuiGtk without a child package.

Why? Of course, it works. I don't understand your design, but if you put
anything in the package GuiGtk, instantiate it in Gui (as TK), then a child
of Gui (Gui.SmpleGad) must see that instance (TK) and you can use anything
declared in the visible part of Gui as TK.*.

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

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

* Re: Generic Library Units?
  2014-10-16  1:21           ` hreba
  2014-10-16  7:04             ` Dmitry A. Kazakov
@ 2014-10-16  7:54             ` Simon Wright
  2014-10-17 12:46               ` hreba
  1 sibling, 1 reply; 12+ messages in thread
From: Simon Wright @ 2014-10-16  7:54 UTC (permalink / raw)


hreba <hreba@terra.com.br> writes:

> As I have dozens of subprogram parameters, I packed them (together
> with the types) into a package parameter GuiGtk and it worked.

This is a "signature package", see Ada 2005 Rationale 12.6[1].

[1] http://www.adaic.org/resources/add_content/standards/95rat/rat95html/rat95-p2-12.html#6

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

* Re: Generic Library Units?
  2014-10-15  7:21         ` Dmitry A. Kazakov
  2014-10-16  1:21           ` hreba
@ 2014-10-16 10:36           ` AdaMagica
  2014-10-17 12:57             ` hreba
  1 sibling, 1 reply; 12+ messages in thread
From: AdaMagica @ 2014-10-16 10:36 UTC (permalink / raw)


Since there is no complete source, I can only guess.

>     generic
>        with package TK is new GuiGtk(<>);	-- this is gui.ads:10
>--      with package TKSG is new GuiGtk.SimpleGad;
--  try this instead:
         with package TKSG is new TK.SimpleGad;
>     package Gui is

GuiGtk is a generic, which seems to have a generic subpackage or child SimpleGad.

You first instantiate GuiGtk, instance is called TK. This implicitly creates the generic TK.SimpleGad (from GuiGtk.SimpleGad), which you can then instantiate as TKSG.


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

* Re: Generic Library Units?
  2014-10-16  7:54             ` Simon Wright
@ 2014-10-17 12:46               ` hreba
  0 siblings, 0 replies; 12+ messages in thread
From: hreba @ 2014-10-17 12:46 UTC (permalink / raw)


On 10/16/2014 04:54 AM, Simon Wright wrote:
> hreba <hreba@terra.com.br> writes:
>
>> As I have dozens of subprogram parameters, I packed them (together
>> with the types) into a package parameter GuiGtk and it worked.
>
> This is a "signature package", see Ada 2005 Rationale 12.6[1].
>
> [1] http://www.adaic.org/resources/add_content/standards/95rat/rat95html/rat95-p2-12.html#6
>

Thanks for the hint. My book is about Ada95, so I wasn't aware of that.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


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

* Re: Generic Library Units?
  2014-10-16 10:36           ` AdaMagica
@ 2014-10-17 12:57             ` hreba
  0 siblings, 0 replies; 12+ messages in thread
From: hreba @ 2014-10-17 12:57 UTC (permalink / raw)


On 10/16/2014 07:36 AM, AdaMagica wrote:
> Since there is no complete source, I can only guess.
>
>>      generic
>>         with package TK is new GuiGtk(<>);	-- this is gui.ads:10
>> --      with package TKSG is new GuiGtk.SimpleGad;
> --  try this instead:
>           with package TKSG is new TK.SimpleGad;
>>      package Gui is
>
> GuiGtk is a generic, which seems to have a generic subpackage or child SimpleGad.
>
> You first instantiate GuiGtk, instance is called TK. This implicitly creates the generic TK.SimpleGad (from GuiGtk.SimpleGad), which you can then instantiate as TKSG.
>

Finally got it to work. With a package SimpleGtk instead of the child 
package GuiGtk.SimpleGad. My structure is now

generic
    with package TK is new GuiGtk(<>);
    with package TKSG is new SimpleGtk(TK);
package Gui is ...
end Gui;

generic
package Gui.SimpleGad is ...
end Gui.SimpleGad;

generic
package GuiGtk is ...
end GuiGtk;

generic
    with package TK is new GuiGtk(<>);
package SimpleGtk is ...
end SimpleGtk;

package MainAux is

    package Toolkit is new GuiGtk;
    package ToolkitSG is new SimpleGtk(Toolkit);
    package GuiTK is new Gui(Toolkit, ToolkitSG);
...
end MainAux;


Thanks to all for your help.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

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

end of thread, other threads:[~2014-10-17 12:57 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-12 14:38 Generic Library Units? hreba
2014-10-12 15:47 ` Dmitry A. Kazakov
2014-10-12 22:39   ` hreba
2014-10-13  7:45     ` Dmitry A. Kazakov
2014-10-15  0:29       ` hreba
2014-10-15  7:21         ` Dmitry A. Kazakov
2014-10-16  1:21           ` hreba
2014-10-16  7:04             ` Dmitry A. Kazakov
2014-10-16  7:54             ` Simon Wright
2014-10-17 12:46               ` hreba
2014-10-16 10:36           ` AdaMagica
2014-10-17 12:57             ` hreba

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