comp.lang.ada
 help / color / mirror / Atom feed
* decomposing large packages
@ 2020-01-08 15:56 mario.blunk.gplus
  2020-01-08 16:36 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: mario.blunk.gplus @ 2020-01-08 15:56 UTC (permalink / raw)


Hello,
I have a package P (spec and body) which is becoming greater and greater as more functionality is implemented. Is there a way to decompose the package into smaller packages S1, S2, etc ? I'm thinking of a kind of "include" directive that refers to the files where stuff has been moved. Example:

The package P in the current state contains:

package P is
 type thing is ...
 procedure m (value : in thing);
 procedure n (value : in thing; temp : in natural);
end package P;

package body P is:
 procedure m (value : in thing) is ...
 procedure n (value : in thing; temp : in natural) is ...
end package body P;

From inside package P the procedure n can be called which is fine so far.
Now I want to take out procedure n and move it into package S1:

package S1 is
 procedure n (value : in thing; temp : in natural);
end package S1;

package body S1 is:
 procedure n (value : in thing; temp : in natural) is ...
end package body S1;

Now procedure n must be visible from inside package P. How can I accomplish that ? I played with child units but did not get what I wanted. The parent P unit must see the procedures and functions of the child units P.S1, P.S2, ... but the compiler complains that procedure n is not defined for type thing in P.
Thanks for your help in advance.




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

* Re: decomposing large packages
  2020-01-08 15:56 decomposing large packages mario.blunk.gplus
@ 2020-01-08 16:36 ` Dmitry A. Kazakov
  2020-01-09  8:25   ` mario.blunk.gplus
  2020-01-08 16:45 ` Simon Wright
  2020-01-08 21:41 ` Shark8
  2 siblings, 1 reply; 11+ messages in thread
From: Dmitry A. Kazakov @ 2020-01-08 16:36 UTC (permalink / raw)


On 2020-01-08 16:56, mario.blunk.gplus@gmail.com wrote:
> Hello,
> I have a package P (spec and body) which is becoming greater and greater as more functionality is implemented. Is there a way to decompose the package into smaller packages S1, S2, etc ? I'm thinking of a kind of "include" directive that refers to the files where stuff has been moved. Example:
> 
> The package P in the current state contains:
> 
> package P is
>   type thing is ...
>   procedure m (value : in thing);
>   procedure n (value : in thing; temp : in natural);
> end package P;

You can use separate bodies. See ARM 10.1.3. E.g. in your case:

----file--- p.adb ---------
package body P is:
    procedure m (value : in thing) is separate;
    procedure n (value : in thing; temp : in natural) is separate;
end P;

----file--- p-m.adb -------
separate (P)
procedure m (value : in thing) is
begin
    ...
end m;

----file--- p-n.adb -------
separate (P)
procedure n (value : in thing; temp : in natural) is
begin
    ...
end n;

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


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

* Re: decomposing large packages
  2020-01-08 15:56 decomposing large packages mario.blunk.gplus
  2020-01-08 16:36 ` Dmitry A. Kazakov
@ 2020-01-08 16:45 ` Simon Wright
  2020-01-09  8:28   ` mario.blunk.gplus
  2020-01-08 21:41 ` Shark8
  2 siblings, 1 reply; 11+ messages in thread
From: Simon Wright @ 2020-01-08 16:45 UTC (permalink / raw)


mario.blunk.gplus@gmail.com writes:

> Now procedure n must be visible from inside package P. How can I
> accomplish that ? I played with child units but did not get what I
> wanted. The parent P unit must see the procedures and functions of the
> child units P.S1, P.S2, ... but the compiler complains that procedure
> n is not defined for type thing in P.

P's body can see P.S1:

   package P.S1 is
      procedure N (Value : Thing) is null; -- save typing :-)
   end P.S1;

   with P.S1;
   package body P is
      procedure M (Value : Thing) is
      begin
         S1.N (Value);
      end M;
   end P;


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

* Re: decomposing large packages
  2020-01-08 15:56 decomposing large packages mario.blunk.gplus
  2020-01-08 16:36 ` Dmitry A. Kazakov
  2020-01-08 16:45 ` Simon Wright
@ 2020-01-08 21:41 ` Shark8
  2 siblings, 0 replies; 11+ messages in thread
From: Shark8 @ 2020-01-08 21:41 UTC (permalink / raw)


On Wednesday, January 8, 2020 at 8:56:48 AM UTC-7, mario.b...@gmail.com wrote:
> 
> Now procedure n must be visible from inside package P. How can I accomplish that?

RENAMES.

-------------------
-- P (Spec)
package P is
 type thing is ...
 procedure m (value : in thing);
 procedure n (value : in thing; temp : in natural);
end package P; 

-------------------
-- S1 (Spec)
package S1 is
 procedure n (value : in thing; temp : in natural);
end package S1;

-------------------
-- P (Body)
with S1;
package body P is
 procedure m (value : in thing) is ...
 procedure n (value : in thing; temp : in natural) renames S1.n;
end P;

> I played with child units but did not get what I wanted. The parent P unit must see the procedures and functions of the child units P.S1, P.S2, ... but the compiler complains that procedure n is not defined for type thing in P.

Here's how you CAN do something like that, given the above specs:
-------------------
-- P.Sn (Spec)
Procedure Sn(value : in thing; temp : in natural);

-------------------
-- P (Body)
with P.Sn;
package body P is
 procedure m (value : in thing) is ...
 procedure n (value : in thing; temp : in natural) renames P.Sn;
end P;


> Thanks for your help in advance.

One thing you could do here is nested+separate units. Given
-------------------
-- P (Spec)
package P is
 type thing is ...
 procedure m (value : in thing);
 procedure n (value : in thing; temp : in natural);
private
 -- Internals could be moved to the top of P's BODY.
 package Internals is
   procedure m (value : in thing);
   procedure n (value : in thing; temp : in natural);
 end Internals;
end P;


-------------------
-- P (Body)
package body P is
 procedure m (value : in thing)                    renames Internals.m;
 procedure n (value : in thing; temp : in natural) renames Internals.n;

  package body Internals is separate;
end P;

-------------------
-- P.Internals (Body)
-- File p-internals.adb
Separate (P)
Package Body Internals is
 procedure m (value : in thing) is
  Begin
   -- implementation.
   null;
  End m;
 
 procedure n (value : in thing; temp : in natural) is
  Begin
    -- implementation.
   null;
  End n;

End Internals;

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

* Re: decomposing large packages
  2020-01-08 16:36 ` Dmitry A. Kazakov
@ 2020-01-09  8:25   ` mario.blunk.gplus
  2020-01-09  8:58     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 11+ messages in thread
From: mario.blunk.gplus @ 2020-01-09  8:25 UTC (permalink / raw)


Thanks Dmitry,
that solves the problem for the moment. When working with subunits, it is not obvious for the newcomer that:
1. the subunit file must be named P-n.adb . Means the same notation must be used as if it where a child unit of P.
2. there is no spec file (P-n.ads) required.
3. in the subunit file P-n.adb there must NOT be an entry like "package body P.n is" (and of course no "end P.n;") as one does in child units.
4. no other procedure or function must exist in P-n.adb .

I wonder why the authors of Ada training books don't point out such things ...

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

* Re: decomposing large packages
  2020-01-08 16:45 ` Simon Wright
@ 2020-01-09  8:28   ` mario.blunk.gplus
  2020-01-09 17:43     ` Simon Wright
  0 siblings, 1 reply; 11+ messages in thread
From: mario.blunk.gplus @ 2020-01-09  8:28 UTC (permalink / raw)


> P's body can see P.S1:
> 
>    package P.S1 is
>       procedure N (Value : Thing) is null; -- save typing :-)
>    end P.S1;
> 
>    with P.S1;
>    package body P is
>       procedure M (Value : Thing) is
>       begin
>          S1.N (Value);
>       end M;
>    end P;

Thanks Simon, but the body of P can't see the specification of S1.


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

* Re: decomposing large packages
  2020-01-09  8:25   ` mario.blunk.gplus
@ 2020-01-09  8:58     ` Dmitry A. Kazakov
  2020-01-09 18:24       ` G. B.
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry A. Kazakov @ 2020-01-09  8:58 UTC (permalink / raw)


On 2020-01-09 09:25, mario.blunk.gplus@gmail.com wrote:

> that solves the problem for the moment. When working with subunits, it is not obvious for the newcomer that:
> 1. the subunit file must be named P-n.adb . Means the same notation must be used as if it where a child unit of P.
> 2. there is no spec file (P-n.ads) required.
> 3. in the subunit file P-n.adb there must NOT be an entry like "package body P.n is" (and of course no "end P.n;") as one does in child units.
> 4. no other procedure or function must exist in P-n.adb .
> 
> I wonder why the authors of Ada training books don't point out such things ...

Because file naming and one compilation unit per source file limitation 
are GNAT specific.

The language does not dictate this. Other compilers use different 
approaches.

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

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

* Re: decomposing large packages
  2020-01-09  8:28   ` mario.blunk.gplus
@ 2020-01-09 17:43     ` Simon Wright
  2020-01-10 20:00       ` mario.blunk.gplus
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Wright @ 2020-01-09 17:43 UTC (permalink / raw)


mario.blunk.gplus@gmail.com writes:

>> P's body can see P.S1:
>> 
>>    package P.S1 is
>>       procedure N (Value : Thing) is null; -- save typing :-)
>>    end P.S1;
>> 
>>    with P.S1;
>>    package body P is
>>       procedure M (Value : Thing) is
>>       begin
>>          S1.N (Value);
>>       end M;
>>    end P;
>
> Thanks Simon, but the body of P can't see the specification of S1.

Oh yes it can. Full test program:

package P is
   type Thing is new Integer;
   procedure M (Value : Thing);
end P;
with P.S1;
package body P is
   procedure M (Value : Thing) is
   begin
      S1.N (Value);
   end M;
end P;
with Ada.Text_IO;
package P.S1 is
   procedure N (Value : Thing);
end P.S1;
package body P.S1 is
   procedure N (Value : Thing) is
   begin
      Ada.Text_IO.Put_Line ("P.S1.N called with " & Value'Img);
   end N;
end P.S1;
with P;
procedure Test is
begin
   P.M (42);
end Test;

===============

$ gnatmake test -f
gcc -c test.adb
gcc -c p.adb
gcc -c p-s1.adb
gnatbind -x test.ali
gnatlink test.ali
gnatlink: warning: executable name "test" may conflict with shell command
$ ./test
P.S1.N called with  42

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

* Re: decomposing large packages
  2020-01-09  8:58     ` Dmitry A. Kazakov
@ 2020-01-09 18:24       ` G. B.
  2020-01-10 20:03         ` mario.blunk.gplus
  0 siblings, 1 reply; 11+ messages in thread
From: G. B. @ 2020-01-09 18:24 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> On 2020-01-09 09:25, mario.blunk.gplus@gmail.com wrote:
> 
>> that solves the problem for the moment. When working with subunits, it
>> is not obvious for the newcomer that:
>> 1.  (...)
>> 4. no other procedure or function must exist in P-n.adb .
>> 
>> I wonder why the authors of Ada training books don't point out such things ...
> 
> Because file naming and one compilation unit per source file limitation 
> are GNAT specific.

The GNAT User's Guide is worth reading, for newcomers in particular. File
naming defaults in:

http://docs.adacore.com/live/wave/gnat_ugn/html/gnat_ugn/gnat_ugn/the_gnat_compilation_model.html#file-naming-topics-and-utilities





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

* Re: decomposing large packages
  2020-01-09 17:43     ` Simon Wright
@ 2020-01-10 20:00       ` mario.blunk.gplus
  0 siblings, 0 replies; 11+ messages in thread
From: mario.blunk.gplus @ 2020-01-10 20:00 UTC (permalink / raw)


Thank you Simon. I believe you and have to figure out why it does not work on my side. The example I gave above is a simplification of a more complex scenario.

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

* Re: decomposing large packages
  2020-01-09 18:24       ` G. B.
@ 2020-01-10 20:03         ` mario.blunk.gplus
  0 siblings, 0 replies; 11+ messages in thread
From: mario.blunk.gplus @ 2020-01-10 20:03 UTC (permalink / raw)


Thank you all for your help. Now I must digest all your answers :-)


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

end of thread, other threads:[~2020-01-10 20:03 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-08 15:56 decomposing large packages mario.blunk.gplus
2020-01-08 16:36 ` Dmitry A. Kazakov
2020-01-09  8:25   ` mario.blunk.gplus
2020-01-09  8:58     ` Dmitry A. Kazakov
2020-01-09 18:24       ` G. B.
2020-01-10 20:03         ` mario.blunk.gplus
2020-01-08 16:45 ` Simon Wright
2020-01-09  8:28   ` mario.blunk.gplus
2020-01-09 17:43     ` Simon Wright
2020-01-10 20:00       ` mario.blunk.gplus
2020-01-08 21:41 ` Shark8

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