comp.lang.ada
 help / color / mirror / Atom feed
* Multiple procedures in the same adb file?
@ 2015-01-11 18:37 John Smith
  2015-01-11 19:05 ` John Smith
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: John Smith @ 2015-01-11 18:37 UTC (permalink / raw)


Hello,

I have a question, what if I want multiple procedures in the same adb file, can that be done?  This is my code right now:

===============================================================================
procedure a_test(A, B : Integer; C : out Integer) is
begin
  C := A + B;
end a_test;

procedure test_procedure is
  output : Integer;
begin
  a_test(23, 34, output);
end test_procedure;
===============================================================================

And this is the compilation error that I got:
===============================================================================
% gnatmake -g test_procedure.adb
gcc -c -g test_procedure.adb
test_procedure.adb:16:01: end of file expected, file can have only one compilation unit
gnatmake: "test_procedure.adb" compilation error
===============================================================================

Basically, if I have the program entrance function, how do I add others so as to break up the logic of the program?


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

* Re: Multiple procedures in the same adb file?
  2015-01-11 18:37 Multiple procedures in the same adb file? John Smith
@ 2015-01-11 19:05 ` John Smith
  2015-01-11 19:51 ` Robert A Duff
  2015-01-11 20:04 ` Jeffrey Carter
  2 siblings, 0 replies; 16+ messages in thread
From: John Smith @ 2015-01-11 19:05 UTC (permalink / raw)


One more question.  Can a file have multiple procedures (as well as a mix of procedures and functions) as well as functions in them as well?  Or would I need to put them into a package?

What does the error "end of file expected, file can have only one compilation unit" mean exactly?

On Sunday, January 11, 2015 at 1:37:48 PM UTC-5, John Smith wrote:
> Hello,
> 
> I have a question, what if I want multiple procedures in the same adb file, can that be done?  This is my code right now:
> 
> ===============================================================================
> procedure a_test(A, B : Integer; C : out Integer) is
> begin
>   C := A + B;
> end a_test;
> 
> procedure test_procedure is
>   output : Integer;
> begin
>   a_test(23, 34, output);
> end test_procedure;
> ===============================================================================
> 
> And this is the compilation error that I got:
> ===============================================================================
> % gnatmake -g test_procedure.adb
> gcc -c -g test_procedure.adb
> test_procedure.adb:16:01: end of file expected, file can have only one compilation unit
> gnatmake: "test_procedure.adb" compilation error
> ===============================================================================
> 
> Basically, if I have the program entrance function, how do I add others so as to break up the logic of the program?

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

* Re: Multiple procedures in the same adb file?
  2015-01-11 18:37 Multiple procedures in the same adb file? John Smith
  2015-01-11 19:05 ` John Smith
@ 2015-01-11 19:51 ` Robert A Duff
  2015-01-11 20:38   ` John Smith
  2015-01-11 21:38   ` Niklas Holsti
  2015-01-11 20:04 ` Jeffrey Carter
  2 siblings, 2 replies; 16+ messages in thread
From: Robert A Duff @ 2015-01-11 19:51 UTC (permalink / raw)


John Smith <yoursurrogategod@gmail.com> writes:

> I have a question, what if I want multiple procedures in the same adb
> file, can that be done?  ...

The simplest thing is to have a single procedure that is your main
procedure, and everything else in packages or generic packages.
The main procedure goes in one file, and each package spec and each
package body in a separate file.  The naming convention is x.ads for
specs and x.adb for bodies, where x is the name of the compilation_unit
(i.e. the package spec or body or procedure body).

You don't have to do that.  There are ways to use different naming
conventions, put multiple compilation units in one files, etc,
but they are a nuisance.  Look up gnatchop, pragma Source_File_Name,
and project files if you really want to do it differently than
the standard GNAT way.

The main procedure doesn't need a spec, but it can have one.
It is unwise to have procedures outside of packages (other than the
main procedure, which Ada annoyingly doesn't allow to be in a package).

For medium-to-large programs, use child packages.  A single root package
(or small number of them), with everything else being child, grandchild,
and so on of the root(s).  The main procedure can be a root, or can be a
child of your single root package.

> ===============================================================================
> procedure a_test(A, B : Integer; C : out Integer) is
> begin
>   C := A + B;
> end a_test;
>
> procedure test_procedure is
>   output : Integer;
> begin
>   a_test(23, 34, output);
> end test_procedure;
> ===============================================================================

Note that you could nest a_test inside test_procedure.

It's a good idea to follow common style rules, such as calling those
A_Test and Test_Procedure.  (But the file names should be in lower
case.)

- Bob

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

* Re: Multiple procedures in the same adb file?
  2015-01-11 18:37 Multiple procedures in the same adb file? John Smith
  2015-01-11 19:05 ` John Smith
  2015-01-11 19:51 ` Robert A Duff
@ 2015-01-11 20:04 ` Jeffrey Carter
  2 siblings, 0 replies; 16+ messages in thread
From: Jeffrey Carter @ 2015-01-11 20:04 UTC (permalink / raw)


On 01/11/2015 11:37 AM, John Smith wrote:
> 
> ===============================================================================
> procedure a_test(A, B : Integer; C : out Integer) is
> begin
>   C := A + B;
> end a_test;
> 
> procedure test_procedure is
>   output : Integer;
> begin
>   a_test(23, 34, output);
> end test_procedure;
> ===============================================================================
> 
> And this is the compilation error that I got:
> ===============================================================================
> % gnatmake -g test_procedure.adb
> gcc -c -g test_procedure.adb
> test_procedure.adb:16:01: end of file expected, file can have only one compilation unit
> gnatmake: "test_procedure.adb" compilation error
> ===============================================================================

GNAT only allows a single compilation unit per file. A compilation unit is a
subprogram declaration, subprogram body, package specification, or pkg body. You
have 2 subprogram bodies in a single file, so GNAT rejects it. Some other
compilers have no problem with multiple compilation units in a single file.

for a simple program like this you probably want to nest A_Test in Test_Procedure:

procedure Test_Procedure is
  procedure A_Test (A : in Integer; B : in Integer; C : out Integer) is
  begin -- A_Test
    C := A + B;
  end A_Test;

  Output : Integer;
begin -- Test_Procedure
  A_Test (A => 23, B => 34, C => Output);
end Test_Procedure;

-- 
Jeff Carter
"It's all right, Taggart. Just a man and a horse being hung out there."
Blazing Saddles
34

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

* Re: Multiple procedures in the same adb file?
  2015-01-11 19:51 ` Robert A Duff
@ 2015-01-11 20:38   ` John Smith
  2015-01-11 21:02     ` Robert A Duff
  2015-01-11 21:38   ` Niklas Holsti
  1 sibling, 1 reply; 16+ messages in thread
From: John Smith @ 2015-01-11 20:38 UTC (permalink / raw)


Hello Bob,

Thanks, that was really helpful.  I got it to work by making the appropriate *.ads and *.adb files.  I also had it working as a nested function.

It seems a tad tedious at first, but it does make sense.  Heck, even C/C++ recommends a similar approach.  You want to separate the declaration from the implementation.

On Sunday, January 11, 2015 at 2:51:32 PM UTC-5, Robert A Duff wrote:
> John Smith <you...@gmail.com> writes:
> 
> > I have a question, what if I want multiple procedures in the same adb
> > file, can that be done?  ...
> 
> The simplest thing is to have a single procedure that is your main
> procedure, and everything else in packages or generic packages.
> The main procedure goes in one file, and each package spec and each
> package body in a separate file.  The naming convention is x.ads for
> specs and x.adb for bodies, where x is the name of the compilation_unit
> (i.e. the package spec or body or procedure body).
> 
> You don't have to do that.  There are ways to use different naming
> conventions, put multiple compilation units in one files, etc,
> but they are a nuisance.  Look up gnatchop, pragma Source_File_Name,
> and project files if you really want to do it differently than
> the standard GNAT way.
> 
> The main procedure doesn't need a spec, but it can have one.
> It is unwise to have procedures outside of packages (other than the
> main procedure, which Ada annoyingly doesn't allow to be in a package).
> 
> For medium-to-large programs, use child packages.  A single root package
> (or small number of them), with everything else being child, grandchild,
> and so on of the root(s).  The main procedure can be a root, or can be a
> child of your single root package.
> 
> > ===============================================================================
> > procedure a_test(A, B : Integer; C : out Integer) is
> > begin
> >   C := A + B;
> > end a_test;
> >
> > procedure test_procedure is
> >   output : Integer;
> > begin
> >   a_test(23, 34, output);
> > end test_procedure;
> > ===============================================================================
> 
> Note that you could nest a_test inside test_procedure.
> 
> It's a good idea to follow common style rules, such as calling those
> A_Test and Test_Procedure.  (But the file names should be in lower
> case.)
> 
> - Bob

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

* Re: Multiple procedures in the same adb file?
  2015-01-11 20:38   ` John Smith
@ 2015-01-11 21:02     ` Robert A Duff
  2015-01-11 21:51       ` John Smith
  2015-01-13  0:11       ` Randy Brukardt
  0 siblings, 2 replies; 16+ messages in thread
From: Robert A Duff @ 2015-01-11 21:02 UTC (permalink / raw)


John Smith <yoursurrogategod@gmail.com> writes:

> Thanks, that was really helpful.

You're welcome.

>...  I got it to work by making the appropriate *.ads and *.adb files.
>I also had it working as a nested function.
>
> It seems a tad tedious at first, ...

Yes, it's a nuisance for small programs.  But for large programs,
one compilation_unit per file with a file-naming convention is
really the only sensible way.  But I must admit, I'd prefer GNAT
to be able to handle multiple compilation_units per file without
so much horsing around.

That's partly because when I'm debugging GNAT, I'm often working
with very small test programs.  If a customer hands me a huge
program that causes GNAT to crash, I'll usually try debugging
it directly first, but if I can't figure it out quickly that way,
I'll try making a small cut-down test that crashes in the same way.
If the small test case contains 30 lines of code in 5 files,
that's just a nuisance.  So I use gnatchop.

Most bug reports are already small.  The biggest one I had to
deal with at AdaCore was about 37,000,000 lines of code.

> ...but it does make sense.  Heck, even C/C++ recommends a similar
> approach.  You want to separate the declaration from the
> implementation.

Right, same idea.

- Bob

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

* Re: Multiple procedures in the same adb file?
  2015-01-11 19:51 ` Robert A Duff
  2015-01-11 20:38   ` John Smith
@ 2015-01-11 21:38   ` Niklas Holsti
  2015-01-12  0:53     ` Robert A Duff
  2015-01-12  0:55     ` Robert A Duff
  1 sibling, 2 replies; 16+ messages in thread
From: Niklas Holsti @ 2015-01-11 21:38 UTC (permalink / raw)


On 15-01-11 21:51 , Robert A Duff wrote:
> It is unwise to have procedures outside of packages

Why "unwise"? I agree it is unusual, but I find it is sometimes useful, 
in particular to have subprograms which are children of packages but are 
their own compilation units. In a layered architecture, such subprograms 
are sort of in a layer between the higher layer that contains the 
declaration of the parent package, and the lower layer that contains the 
body of that package.

In language-lawyer terms, perhaps such subprograms are not really 
"outside of packages", because child units are in some sense "inside" 
their parents, but the child subprograms are not "inside" any package in 
terms of source-code files.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

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

* Re: Multiple procedures in the same adb file?
  2015-01-11 21:02     ` Robert A Duff
@ 2015-01-11 21:51       ` John Smith
  2015-01-12  0:53         ` Robert A Duff
  2015-01-12  0:55         ` Robert A Duff
  2015-01-13  0:11       ` Randy Brukardt
  1 sibling, 2 replies; 16+ messages in thread
From: John Smith @ 2015-01-11 21:51 UTC (permalink / raw)


37,000,000 lines of code?  What was the application supposed to do?  Simulate planet earth?

On Sunday, January 11, 2015 at 4:02:21 PM UTC-5, Robert A Duff wrote:
> John Smith <you...@gmail.com> writes:
> 
> > Thanks, that was really helpful.
> 
> You're welcome.
> 
> >...  I got it to work by making the appropriate *.ads and *.adb files.
> >I also had it working as a nested function.
> >
> > It seems a tad tedious at first, ...
> 
> Yes, it's a nuisance for small programs.  But for large programs,
> one compilation_unit per file with a file-naming convention is
> really the only sensible way.  But I must admit, I'd prefer GNAT
> to be able to handle multiple compilation_units per file without
> so much horsing around.
> 
> That's partly because when I'm debugging GNAT, I'm often working
> with very small test programs.  If a customer hands me a huge
> program that causes GNAT to crash, I'll usually try debugging
> it directly first, but if I can't figure it out quickly that way,
> I'll try making a small cut-down test that crashes in the same way.
> If the small test case contains 30 lines of code in 5 files,
> that's just a nuisance.  So I use gnatchop.
> 
> Most bug reports are already small.  The biggest one I had to
> deal with at AdaCore was about 37,000,000 lines of code.
> 
> > ...but it does make sense.  Heck, even C/C++ recommends a similar
> > approach.  You want to separate the declaration from the
> > implementation.
> 
> Right, same idea.
> 
> - Bob



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

* Re: Multiple procedures in the same adb file?
  2015-01-11 21:38   ` Niklas Holsti
@ 2015-01-12  0:53     ` Robert A Duff
  2015-01-12  9:01       ` J-P. Rosen
  2015-01-12  0:55     ` Robert A Duff
  1 sibling, 1 reply; 16+ messages in thread
From: Robert A Duff @ 2015-01-12  0:53 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> On 15-01-11 21:51 , Robert A Duff wrote:
>> It is unwise to have procedures outside of packages
>
> Why "unwise"?

Because sometimes you need to add new stuff (another related procedure,
for example), and then there's no good place to put it.  If the existing
procedure is in a package, then that's where you put it.

This happened to me:  Existing code:

    function Some_Root_Package.Some_Function(...) return String;

Now I happen to know that it always returns String(1..20).
And returning known-length strings is more efficient,
and this one is a bottleneck, so it's worth changing to
something like:

    subtype String_20 is String(1..20);
    function Some_Function(...) return String_20;

But that doesn't work without adding a new package, which breaks
compatibility.  And this was a widely-used library, so I couldn't do
that.  And String_20 really doesn't belong in Some_Root_Package,
nor anywhere else than the package that Some_Function is (directly) in
(which didn't exist!).

If the original programmer had put Some_Function in a child package
Some_Root_Package.Some_Package in the first place, then I wouldn't have
had these problems.

I admit: these concerns are only significant for widely-used libraries.
If I had been working on a program instead of a library, I would have
just moved Some_Function into a package, and modified all the call
sites.  But it's probably a good idea to get in the habit of using
"library-programming" style even when doing "program-programming",
if it's not too much trouble.

Besides, it complicates the language quite a bit to have misc stuff
allowed as compilation units (e.g. task body subunits).  I would prefer
that the only unit of separate compilation be the package (and maybe
generic package).

>... I agree it is unusual, but I find it is sometimes useful,
> in particular to have subprograms which are children of packages but are
> their own compilation units. In a layered architecture, such subprograms
> are sort of in a layer between the higher layer that contains the
> declaration of the parent package, and the lower layer that contains the
> body of that package.

Sure, but you can do that with another package just as well as
with a procedure.

> In language-lawyer terms, perhaps such subprograms are not really
> "outside of packages", because child units are in some sense "inside"
> their parents, but the child subprograms are not "inside" any package in
> terms of source-code files.

Yes, you're right.  In fact, everything is logically nested within
package Standard, so everything is in a package.  But I meant that
everything should be physically/textually nested within a package,
and packages (and generic packages) should be the only
separately-compiled things.  And main procedures should be
(textually) in packages, instead of as standalone procedures
(and that part is not Ada -- just my preference for how it ought
to be!).

- Bob


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

* Re: Multiple procedures in the same adb file?
  2015-01-11 21:51       ` John Smith
@ 2015-01-12  0:53         ` Robert A Duff
  2015-01-12  0:55         ` Robert A Duff
  1 sibling, 0 replies; 16+ messages in thread
From: Robert A Duff @ 2015-01-12  0:53 UTC (permalink / raw)


John Smith <yoursurrogategod@gmail.com> writes:

> 37,000,000 lines of code?  What was the application supposed to do?
> Simulate planet earth?

;-)

I think it was air traffic control or railroad switching control,
or something like that.

- Bob


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

* Re: Multiple procedures in the same adb file?
  2015-01-11 21:38   ` Niklas Holsti
  2015-01-12  0:53     ` Robert A Duff
@ 2015-01-12  0:55     ` Robert A Duff
  1 sibling, 0 replies; 16+ messages in thread
From: Robert A Duff @ 2015-01-12  0:55 UTC (permalink / raw)


Oops, sorry for the email.  I meant to post to the newsgroup -- hit the
wrong button.

- Bob

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

* Re: Multiple procedures in the same adb file?
  2015-01-11 21:51       ` John Smith
  2015-01-12  0:53         ` Robert A Duff
@ 2015-01-12  0:55         ` Robert A Duff
  1 sibling, 0 replies; 16+ messages in thread
From: Robert A Duff @ 2015-01-12  0:55 UTC (permalink / raw)


Oops, sorry for the email.  I meant to post to the newsgroup -- hit the
wrong button.

- Bob


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

* Re: Multiple procedures in the same adb file?
  2015-01-12  0:53     ` Robert A Duff
@ 2015-01-12  9:01       ` J-P. Rosen
  2015-01-12 14:57         ` Robert A Duff
  0 siblings, 1 reply; 16+ messages in thread
From: J-P. Rosen @ 2015-01-12  9:01 UTC (permalink / raw)


Le 12/01/2015 01:53, Robert A Duff a écrit :
> This happened to me:  Existing code:
> 
>     function Some_Root_Package.Some_Function(...) return String;
> 
> Now I happen to know that it always returns String(1..20).
> And returning known-length strings is more efficient,
> and this one is a bottleneck, so it's worth changing to
> something like:
> 
>     subtype String_20 is String(1..20);
>     function Some_Function(...) return String_20;
> 
> But that doesn't work without adding a new package, which breaks
> compatibility.  And this was a widely-used library, so I couldn't do
> that.  And String_20 really doesn't belong in Some_Root_Package,
> nor anywhere else than the package that Some_Function is (directly) in
> (which didn't exist!).

Put the function in a package, and declare Some_Function as:
function Some_Function (...) renames New_Package.Some_Function;

(For compatibility, new programs would use directly the function in the
package).

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


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

* Re: Multiple procedures in the same adb file?
  2015-01-12  9:01       ` J-P. Rosen
@ 2015-01-12 14:57         ` Robert A Duff
  2015-01-13  0:09           ` Randy Brukardt
  0 siblings, 1 reply; 16+ messages in thread
From: Robert A Duff @ 2015-01-12 14:57 UTC (permalink / raw)


"J-P. Rosen" <rosen@adalog.fr> writes:

> Le 12/01/2015 01:53, Robert A Duff a écrit :
>> This happened to me:  Existing code:
>> 
>>     function Some_Root_Package.Some_Function(...) return String;
>> 
>> Now I happen to know that it always returns String(1..20).
>> And returning known-length strings is more efficient,
>> and this one is a bottleneck, so it's worth changing to
>> something like:
>> 
>>     subtype String_20 is String(1..20);
>>     function Some_Function(...) return String_20;
>> 
>> But that doesn't work without adding a new package, which breaks
>> compatibility.  And this was a widely-used library, so I couldn't do
>> that.  And String_20 really doesn't belong in Some_Root_Package,
>> nor anywhere else than the package that Some_Function is (directly) in
>> (which didn't exist!).
>
> Put the function in a package, and declare Some_Function as:
> function Some_Function (...) renames New_Package.Some_Function;
>
> (For compatibility, new programs would use directly the function in the
> package).

I started to reply, "Good idea", but then I remembered it doesn't work.
A library unit can only rename another library unit.  If it did work,
I'd still prefer to use packages from the start.

I see AARM-10.1.1(14.a) explains why we have this restriction, in part
"because they wouldn't be particularly useful".  Probably written by
somebody who doesn't like library subprograms.  ;-)

- Bob


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

* Re: Multiple procedures in the same adb file?
  2015-01-12 14:57         ` Robert A Duff
@ 2015-01-13  0:09           ` Randy Brukardt
  0 siblings, 0 replies; 16+ messages in thread
From: Randy Brukardt @ 2015-01-13  0:09 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wcck30s2gi1.fsf@shell01.TheWorld.com...
...
> I see AARM-10.1.1(14.a) explains why we have this restriction, in part
> "because they wouldn't be particularly useful".  Probably written by
> somebody who doesn't like library subprograms.  ;-)

Somebody with the initials RAD? ;-)

                      Randy.



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

* Re: Multiple procedures in the same adb file?
  2015-01-11 21:02     ` Robert A Duff
  2015-01-11 21:51       ` John Smith
@ 2015-01-13  0:11       ` Randy Brukardt
  1 sibling, 0 replies; 16+ messages in thread
From: Randy Brukardt @ 2015-01-13  0:11 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wcc7fwt9gkr.fsf@shell01.TheWorld.com...
...
> Most bug reports are already small.  The biggest one I had to
> deal with at AdaCore was about 37,000,000 lines of code.

I think I'm now going to have nightmares about getting a bug report like 
that. :-) I fear I get frustrated on reasonable-sized bugs, I don't know if 
I'd know how to start with that one. (Of course, I'd probably never get it, 
because it would probably exceed the size-limit on something our e-mail 
server will accept.)

                                      Randy.




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

end of thread, other threads:[~2015-01-13  0:11 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-11 18:37 Multiple procedures in the same adb file? John Smith
2015-01-11 19:05 ` John Smith
2015-01-11 19:51 ` Robert A Duff
2015-01-11 20:38   ` John Smith
2015-01-11 21:02     ` Robert A Duff
2015-01-11 21:51       ` John Smith
2015-01-12  0:53         ` Robert A Duff
2015-01-12  0:55         ` Robert A Duff
2015-01-13  0:11       ` Randy Brukardt
2015-01-11 21:38   ` Niklas Holsti
2015-01-12  0:53     ` Robert A Duff
2015-01-12  9:01       ` J-P. Rosen
2015-01-12 14:57         ` Robert A Duff
2015-01-13  0:09           ` Randy Brukardt
2015-01-12  0:55     ` Robert A Duff
2015-01-11 20:04 ` Jeffrey Carter

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