comp.lang.ada
 help / color / mirror / Atom feed
* how to organize source code for a complete software? Thanks!
@ 2011-10-09 16:20 Jinsong Zhao
  2011-10-09 17:16 ` stefan-lucks
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Jinsong Zhao @ 2011-10-09 16:20 UTC (permalink / raw)


Hi there,

I am new to Ada, and I just have some experiences in using Fortran.

When using Fortran, I generally put each subroutine or function in a 
separate file, e.g., dot.for for dot product of two vectors. Then a 
main.for that call the necessary subroutine or functions. It seems to be 
rational.

When I using Ada, I don't know how to do. There are procedure, function, 
package, package body, and so on (with different file extension, e.g., 
ada, adb, ads, ...). And there is no main program.

Would anyone here like to give a an analogy between the source code 
organization in Fortran and the one in Ada?

And, please, if you like, point me a small, complete open source 
software in Ada (not a library or package). I should be compiled and 
run. I just hope to learn how to start a software in Ada by example.

Any suggestions or comments will be really appreciated. Thanks in advance.

Regards,
Jinsong



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 16:20 how to organize source code for a complete software? Thanks! Jinsong Zhao
@ 2011-10-09 17:16 ` stefan-lucks
  2011-10-10  5:52   ` Jinsong Zhao
  2011-10-09 17:37 ` Yannick Duchêne (Hibou57)
  2011-10-09 17:48 ` Niklas Holsti
  2 siblings, 1 reply; 14+ messages in thread
From: stefan-lucks @ 2011-10-09 17:16 UTC (permalink / raw)


> I am new to Ada, and I just have some experiences in using Fortran.
> 
> When using Fortran, I generally put each subroutine or function in a separate
> file, e.g., dot.for for dot product of two vectors. Then a main.for that call
> the necessary subroutine or functions. It seems to be rational.
> 
> When I using Ada, I don't know how to do. There are procedure, function,
> package, package body, and so on (with different file extension, e.g., ada,
> adb, ads, ...). And there is no main program.

1. Any parameterless procedure, which is not "local" inside another 
   function/procedure or inside a package, can be the main program.

2. As a rule of thumb for beginners: Put your auxiliary subprograms (in 
   Ada: a subprogram is either a function or a procedure) and the requited 
   type definition into packages. Write a single parameterless main 
   procedure as the "main" procedure, but give it a meaningful name 
   ("Solve_Linear_Equations" or "Delete_File" rather than "Main"). Put 
   that procedure into a file of its own. 

2a. Note that a package consists of a specification and an implementation, 
    which are usually put into TWO different files (e.g., "name.ads" for 
    the spec and "name.adb" for the implementation body). 

2b. When you are more advanced in programming in Ada, you may sometimes 
    want to compile "separate" subprograms without wrapping them into 
    packages.  

3. Compile the main procedure (e.g., by calling "gnatmake" if you use the 
   gnat Ada compiler) -- your compiler will know which packages it needs 
   to compile. 

> And, please, if you like, point me a small, complete open source software in
> Ada (not a library or package). I should be compiled and run. I just hope to
> learn how to start a software in Ada by example.

Examples: 
  <http://rosettacode.org/wiki/Linear_congruential_generator#Ada> 
  <http://rosettacode.org/wiki/Ternary_logic#Ada>

The linear congruential example would consist of three files: 
  1. the specification "lcg.ads",
  2. the implementation "lcg.adb", and
  3. the main program "run_lcgs.adb". 
(These are the gnat/gcc naming conventions, look into your compiler 
documentation if you use another compiler.)

As an easy exercise for the reader, try to figure out which three files 
the ternary logic example would consist of. 


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 16:20 how to organize source code for a complete software? Thanks! Jinsong Zhao
  2011-10-09 17:16 ` stefan-lucks
@ 2011-10-09 17:37 ` Yannick Duchêne (Hibou57)
  2011-10-10  6:02   ` Jinsong Zhao
  2011-10-09 17:48 ` Niklas Holsti
  2 siblings, 1 reply; 14+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2011-10-09 17:37 UTC (permalink / raw)


Welcome Jinsong :-)

Le Sun, 09 Oct 2011 18:20:53 +0200, Jinsong Zhao <jszhao@yeah.net> a écrit:
> When I using Ada, I don't know how to do. There are procedure, function,  
> package, package body, and so on (with different file extension, e.g.,  
> ada, adb, ads, ...). And there is no main program.
*.ada is not that common. Where did you see it ? *.adb and *.ads are not  
Ada specific, these are GNAT specific instead. The Ada Reference Manual  
does not specify file layout, nor file extensions.

So this all depend on your compiler, which is GNAT here it seems (you may  
also have a look at Janus Ada from RRSoftware, if Ada 95 is enough for  
you).

The file layout for GNAT is as this:
    Package specification in *.ads files
    Package body in *.adb
    Main procedure in *.adb
    Separate body in *.adb

In few words: specifications goes to *.ads, which stands for Ada  
Specification, and implementations goes to *.adb, which stands for Ada  
Body.

File names (not extensions) must be derived from compilation unit names,  
with this transformation applied: all uppercase characters turned into  
lowercase and periods turned into dashes.

Example: your have a package name My_AI_Lib.Knowledge (to say we play with  
fun things). Then the specification will be in my_ai_lib-knowledge.ads,  
the body will be in my_ai_lib-knowledge.adb. If your test main program is  
a procedure named Test_My_AI, then it will belong to a file named  
test_my_ai.adb

Similar things applies with separate bodies and child packages.

Worth to read at your stage:
http://www.adacore.com/wp-content/files/auto_update/gnat-unw-docs/html/gnat_ugn_2.html

> Would anyone here like to give a an analogy between the source code  
> organization in Fortran and the one in Ada?
Unless you use separate bodies all over the place, there is no way to  
compare Ada layout and Fortran layout. With Ada, multiple procedure may  
belong to a single package. May be there exist some compiler which  
requires each procedure to reside in its own file, but GNAT don't use such  
a layout. Keep in mind this is compiler specific!

> And, please, if you like, point me a small, complete open source  
> software in Ada (not a library or package). I should be compiled and  
> run. I just hope to learn how to start a software in Ada by example.
I did not checked all of it, but here is a good list of samples (there may  
be some others too):
http://sandbox.mc.edu/~bennet/ada/examples/

> Any suggestions or comments will be really appreciated. Thanks in  
> advance.
Yes, start with this:

>>>
-- Hello World, the quick easy form.

with Ada.Text_IO; use Ada.Text_IO;

procedure Hello is
begin
    Put_Line ("Hello, Bonjour, Ohayo");
end;
>>>

Second alternative, for people who enjoy to be more formal or strict:

>>>
-- Hello World, the proud form (lol).

with Ada.Text_IO;

procedure Hello is
    package IO renames Ada.Text_IO;
    Greeting_Message : constant String := "Hello, Bonjour, Ohayo";
begin
    IO.Put_Line (Greeting_Message);
end Hello;
>>>

> Regards,
> Jinsong
Have a nice time Jinsong


-- 
“Syntactic sugar causes cancer of the semi-colons.”  [Epigrams on  
Programming — Alan J. — P. Yale University]
“Structured Programming supports the law of the excluded muddle.” [Idem]
Java: Write once, Never revisit



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 16:20 how to organize source code for a complete software? Thanks! Jinsong Zhao
  2011-10-09 17:16 ` stefan-lucks
  2011-10-09 17:37 ` Yannick Duchêne (Hibou57)
@ 2011-10-09 17:48 ` Niklas Holsti
  2011-10-09 18:37   ` Ludovic Brenta
  2011-10-10  6:45   ` Jinsong Zhao
  2 siblings, 2 replies; 14+ messages in thread
From: Niklas Holsti @ 2011-10-09 17:48 UTC (permalink / raw)


On 11-10-09 18:20 , Jinsong Zhao wrote:
> Hi there,
>
> I am new to Ada, and I just have some experiences in using Fortran.

Welcome, then. May I ask what attracted you to Ada? I am asking partly 
out of curiosity, but also because if you tell us what you hope to gain 
by using Ada, we may better advise you on how to organize your code, and 
on other Ada usage.

> When using Fortran, I generally put each subroutine or function in a
> separate file, e.g., dot.for for dot product of two vectors. Then a
> main.for that call the necessary subroutine or functions. It seems to be
> rational.
>
> When I using Ada, I don't know how to do.

If you like, you can do exactly as you are accustomed to doing in 
Fortran (although this would be an unusual style for Ada). You can put 
each Ada function or procedure in its own compilation unit.

The only difference is that you will typically write two files per 
subprogram, one to specify the subprogram (its name, its parameters, and 
its return type, if it is a function) and one to implement the 
subprogram by giving its body, which contains the declarations of the 
local variables and the statements that are executed in the subprogram.

For example, let's make a function that adds two Float numbers and 
returns their sum, and let's call this function Add. In the following, I 
assume you are using the GNAT Ada compiler and its default conventions 
for source file names.

The Add function will have a specification (or declaration) file 
add.ads, which contains this one line:

    function Add (A, B : Float) return Float;

Any other subprogram that needs to use (call) the Add function will 
start with the line

    with Add;

which makes the compiler read the file add.ads, so that the compiler 
knows the name, parameters, and return type of Add.

The Add function will have an implementation (or body) file add.adb, 
which contains these five lines:

    function Add (A, B : Float) return Float
    is
    begin
       return A + B;
    end Add;

Assume that your main subprogram should use Add to compute the sum of 
the numbers 15.6 and 88.2 and print out the sum, and you give this 
procedure the name Main, then you would write it as the file main.adb 
with the following content:

    with Add;          -- So that we can call Add, below.
    with Ada.Text_IO;  -- So that we can call Put_Line, below.
    procedure Main
    is
    begin
       Ada.Text_IO.Put_Line (Float'Image (Add (15.6, 88.2)));
    end Main;

This program thus consists of three files: add.ads, add.adb, main.adb. 
To compile this program with GNAT, you only have to give the command

    gnatmake main

and GNAT will compile all three files and create an executable called main.

> There are procedure, function,
> package, package body, and so on (with different file extension, e.g.,
> ada, adb, ads, ...). And there is no main program.

The main program is just a parameterless procedure, like the Main above. 
It can be called anything you like; its name usually (but not 
necessarily) becomes the name of the program executable.

The one-subprogram-per-file method shown above, which is what you have 
been doing in Fortran, breaks down when you have subprograms that need 
to access some global data, for example like Fortran COMMON data. If you 
don't want to pass all this data in parameters, you must put it in a 
package. Then you can have two Ada designs, one that is very similar to 
Fortran COMMON, and the other that is more typical for Ada.

Here is how to do the Fortran-like design. Suppose that the Add 
function, above, should also include in the sum the value of a global 
variable Offset, that relates to some "scale" that the program is using, 
but you don't want to pass Offset as a parameter to Add. In Fortran, you 
could declare a COMMON area called Scale, containing a variable called 
Offset. In Ada, this can be implemented as a package Scale with a public 
variable Offset. Such a package is written in one file, scale.ads, as 
follows:

    package Scale
    is
       Offset : Float := 0.0;
    end Scale;

Here I also gave the Offset an initial value, just to avoid using an 
undefined value.

The Add function would now be written as follows, in add.adb:

    with Scale;
    function Add (A, B : Float) return Float
    is
    begin
       return A + B + Scale.Offset;
    end Add;

Note that:

- the line "with Scale" gives us access to the data in Scale, but

- you still have to use the qualified name, Scale.Offset, to refer
   to the variable Offset in the package Scale.

If you add a line after "with Scale", saying "use Scale", you can use 
just the name Offset instead of Scale.Offset. But many Ada programmers 
think that such "use clauses" should be used very sparingly, and that 
writing Scale.Offset is clearer.

Note that the file add.ads was not changed, since the text in that file 
does not have to refer to the Scale package.

Suppose now that your Main subprogram needs to Add the same two numbers 
as before, but with an Offset of 3.2. This would be written as follows, 
in main.adb:

    with Add;          -- So that we can call Add, below.
    with Scale;        -- So that we can access Scale.Offset, below.
    with Ada.Text_IO;  -- So that we can call Put_Line, below.
    procedure Main
    is
    begin
       Scale.Offset := 3.2;
       Ada.Text_IO.Put_Line (Float'Image (Add (15.6, 88.2));
    end Main;

> Would anyone here like to give a an analogy between the source code
> organization in Fortran and the one in Ada?

The example above was how one would represent Fortran COMMON in Ada 
packages, in a Fortran-like way: write the COMMON area as a package 
(*.ads file) with public variables representing the COMMON data, and 
then "with" this package in any subprogram (*.adb file) that needs to 
use this data.

However, this style is not the typical Ada style. The more common style 
in Ada is to make packages that contain both data and subprograms, and 
to make the data private as far as possible.

This is stretching the above example a bit, but the principle would be 
to put the Add function in the Scale package, since it needs to use 
Scale.Offset, and to move the Offset variable into the package body, so 
that it cannot be accessed from outside the package. The file scale.ads 
would now look like this:

    package Scale
    is
       function Add (A, B : Float) return Float;
       procedure Set_Offset (To : in Float);
    end Scale;

The declaration of the Offset variable, and the bodies of the two 
subprograms, would now be written in the "body file" for Scale, which is 
called scale.adb and contains this:

    package body Scale
    is

       Offset : Float := 0.0;

       function Add (A, B : Float) return Float
       is
       begin
          return A + B + Offset;
       end Add;

       procedure Set_Offset (To : in Float)
       is
       begin
          Offset := To;
       end Set_Offset;

    end Scale;

Of course, the files add.ads and add.adb are now unnecessary, since Add 
is both declared and implemented within package Scale, thus in the files 
scale.ads and scale.adb.

The Main subprogram in main.adb would now have this form:

    with Scale;        -- So that we can use it, below.
    with Ada.Text_IO;  -- So that we can call Put_Line, below.
    procedure Main
    is
    begin
       Scale.Set_Offset (3.2);
       Ada.Text_IO.Put_Line (Float'Image (Scale.Add (15.6, 88.2));
    end Main;

The single command "gnatmake main" is still enough to compile the 
program, although Main now uses other packages.

If you have any other subprograms that are also related to the Scale, 
and need to use Scale.Offset, you would put them in package Scale, too.

Of course, finding a good package structure can become complex if you 
have something like a Fortran program with several COMMON areas, and 
have several subprograms that use different subsets of the COMMON areas. 
You can fall back on the Fortran-like structure (one package per COMMON 
area, with public data), or look up some texts on "information hiding" 
and "software architecture", but even so, there are usually several ways 
to slice the cake, and the best way is often a matter of taste.

> And, please, if you like, point me a small, complete open source
> software in Ada (not a library or package). I should be compiled and
> run. I just hope to learn how to start a software in Ada by example.

Sorry, my internet access at present (on travel) is so wonky that I have 
no web access, in practice.

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



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 17:48 ` Niklas Holsti
@ 2011-10-09 18:37   ` Ludovic Brenta
  2011-10-09 21:24     ` J-P. Rosen
  2011-10-10 12:09     ` Jinsong Zhao
  2011-10-10  6:45   ` Jinsong Zhao
  1 sibling, 2 replies; 14+ messages in thread
From: Ludovic Brenta @ 2011-10-09 18:37 UTC (permalink / raw)


Niklas Holsti writes on comp.lang.ada:
> On 11-10-09 18:20 , Jinsong Zhao wrote:
>> Hi there,
>>
>> I am new to Ada, and I just have some experiences in using Fortran.
>
> Welcome, then. May I ask what attracted you to Ada? I am asking partly
> out of curiosity, but also because if you tell us what you hope to
> gain by using Ada, we may better advise you on how to organize your
> code, and on other Ada usage.

I am curious, too.

>> When using Fortran, I generally put each subroutine or function in a
>> separate file, e.g., dot.for for dot product of two vectors. Then a
>> main.for that call the necessary subroutine or functions. It seems to
>> be rational.

OK but where do you place variables that are shared by multiple
subroutines or functions?  Where do you place type declarations?  This
is quite crucial for my point below.

>> When I using Ada, I don't know how to do.

In addition to the rules of thumb given by others, I'll now explain the
reasoning behind a proper choice of where to place your subprograms.
It's all about _visibility_.

package P is
   -- this part is visible to anyone who says "with P;"
private
   -- this part is visible only from the body of P
end P;

package body P is
   -- this part is completely hidden
end P;

procedure Proc is
   -- this part is completely hidden
begin
   -- this part is completely hidden
end Proc;

A subprogram declared in the package P can see everything in the public
and private parts of the spec; it can also see everything that has been
declared above it inside the body.  Thus, a package spec will normally
look like:

package P is
   type T is private;
   procedure Foo (Param : in out T);
private
   type T is ...;
end P;

If several subprograms use the same type T in their specs, then they
should all be declared in the same package.  So, my advice to you is to
organize your sources not in terms of subprograms, but in terms of
types; each major type should be in a package of its own, along with all
the subprograms that operate on it.  One example that I wrote is here:

http://green.ada-france.org:8081/revision/browse/108fe173864fa16185a547d486849a475dd3c2a3

You will find one main subprogram (test.adb), one spec
(s_expression.ads) declaring a type T and all subprograms operating on
it (the type T is private and its details are in the private part of the
spec), and one package body (s_expression.adb) containing the
implementation of those subprograms.

-- 
Ludovic Brenta.



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 18:37   ` Ludovic Brenta
@ 2011-10-09 21:24     ` J-P. Rosen
  2011-10-10 12:09     ` Jinsong Zhao
  1 sibling, 0 replies; 14+ messages in thread
From: J-P. Rosen @ 2011-10-09 21:24 UTC (permalink / raw)


Le 09/10/2011 20:37, Ludovic Brenta a �crit :
> OK but where do you place variables that are shared by multiple
> subroutines or functions?  Where do you place type declarations?  This
> is quite crucial for my point below.
In Fortran, you would place them in Common blocks.

You can have the same effect in Ada by having packages that contain only
(types and) variables. I'm not saying it is recommended practice in Ada,
although some design methods (SA) lead you to group subprograms on one
side and data on the other side. Of course, the OO wave does the
opposite (group related subprograms and data).

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Adalog a d�m�nag� / Adalog has moved:
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 17:16 ` stefan-lucks
@ 2011-10-10  5:52   ` Jinsong Zhao
  0 siblings, 0 replies; 14+ messages in thread
From: Jinsong Zhao @ 2011-10-10  5:52 UTC (permalink / raw)


On 2011-10-10 1:16, stefan-lucks@see-the.signature wrote:
>> I am new to Ada, and I just have some experiences in using Fortran.
>>
>> When using Fortran, I generally put each subroutine or function in a separate
>> file, e.g., dot.for for dot product of two vectors. Then a main.for that call
>> the necessary subroutine or functions. It seems to be rational.
>>
>> When I using Ada, I don't know how to do. There are procedure, function,
>> package, package body, and so on (with different file extension, e.g., ada,
>> adb, ads, ...). And there is no main program.
>
> 1. Any parameterless procedure, which is not "local" inside another
>     function/procedure or inside a package, can be the main program.
>
> 2. As a rule of thumb for beginners: Put your auxiliary subprograms (in
>     Ada: a subprogram is either a function or a procedure) and the requited
>     type definition into packages. Write a single parameterless main
>     procedure as the "main" procedure, but give it a meaningful name
>     ("Solve_Linear_Equations" or "Delete_File" rather than "Main"). Put
>     that procedure into a file of its own.
>
> 2a. Note that a package consists of a specification and an implementation,
>      which are usually put into TWO different files (e.g., "name.ads" for
>      the spec and "name.adb" for the implementation body).
>
> 2b. When you are more advanced in programming in Ada, you may sometimes
>      want to compile "separate" subprograms without wrapping them into
>      packages.
>
> 3. Compile the main procedure (e.g., by calling "gnatmake" if you use the
>     gnat Ada compiler) -- your compiler will know which packages it needs
>     to compile.

Thank you very much. The above statements give me more information than 
what I get from the books available to me here. Now, I think I know how 
to layout my small program.

>
>> And, please, if you like, point me a small, complete open source software in
>> Ada (not a library or package). I should be compiled and run. I just hope to
>> learn how to start a software in Ada by example.
>
> Examples:
>    <http://rosettacode.org/wiki/Linear_congruential_generator#Ada>
>    <http://rosettacode.org/wiki/Ternary_logic#Ada>

It's a nice place for me. Thanks!

>
> The linear congruential example would consist of three files:
>    1. the specification "lcg.ads",
>    2. the implementation "lcg.adb", and
>    3. the main program "run_lcgs.adb".
> (These are the gnat/gcc naming conventions, look into your compiler
> documentation if you use another compiler.)
>
> As an easy exercise for the reader, try to figure out which three files
> the ternary logic example would consist of.
>
>
I think I can get the answer:
1. the specification "logic.ads",
2. the implementation "logic.adb", and
3. the main program "test_tri_logic.adb".

Thanks again for your informative reply and the example codes.

Regards,
Jinsong



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 17:37 ` Yannick Duchêne (Hibou57)
@ 2011-10-10  6:02   ` Jinsong Zhao
  2011-10-10 13:15     ` Paul Colin Gloster
  0 siblings, 1 reply; 14+ messages in thread
From: Jinsong Zhao @ 2011-10-10  6:02 UTC (permalink / raw)


On 2011-10-10 1:37, Yannick Duchêne (Hibou57) wrote:
> Welcome Jinsong :-)
>
> Le Sun, 09 Oct 2011 18:20:53 +0200, Jinsong Zhao <jszhao@yeah.net> a écrit:
>> When I using Ada, I don't know how to do. There are procedure,
>> function, package, package body, and so on (with different file
>> extension, e.g., ada, adb, ads, ...). And there is no main program.
> *.ada is not that common. Where did you see it ? *.adb and *.ads are not
> Ada specific, these are GNAT specific instead. The Ada Reference Manual
> does not specify file layout, nor file extensions.

Oops, I have seen *.ada somewhere, but I don't recall it...

>
> So this all depend on your compiler, which is GNAT here it seems (you
> may also have a look at Janus Ada from RRSoftware, if Ada 95 is enough
> for you).
>
> The file layout for GNAT is as this:
> Package specification in *.ads files
> Package body in *.adb
> Main procedure in *.adb
> Separate body in *.adb
>
> In few words: specifications goes to *.ads, which stands for Ada
> Specification, and implementations goes to *.adb, which stands for Ada
> Body.
>
> File names (not extensions) must be derived from compilation unit names,
> with this transformation applied: all uppercase characters turned into
> lowercase and periods turned into dashes.
>
> Example: your have a package name My_AI_Lib.Knowledge (to say we play
> with fun things). Then the specification will be in
> my_ai_lib-knowledge.ads, the body will be in my_ai_lib-knowledge.adb. If
> your test main program is a procedure named Test_My_AI, then it will
> belong to a file named test_my_ai.adb
>
> Similar things applies with separate bodies and child packages.
>
> Worth to read at your stage:
> http://www.adacore.com/wp-content/files/auto_update/gnat-unw-docs/html/gnat_ugn_2.html
>

Yes, I use GNAT as the compiler. However, I didn't find a way to obtain 
those information before I post and get help here.

>
>> Would anyone here like to give a an analogy between the source code
>> organization in Fortran and the one in Ada?
> Unless you use separate bodies all over the place, there is no way to
> compare Ada layout and Fortran layout. With Ada, multiple procedure may
> belong to a single package. May be there exist some compiler which
> requires each procedure to reside in its own file, but GNAT don't use
> such a layout. Keep in mind this is compiler specific!

There is many difference between the Ada layout and Fortran layout, 
however, I just have some experiences in Fortran. I will try my best to 
do something similar with the Ada style.
>
>> And, please, if you like, point me a small, complete open source
>> software in Ada (not a library or package). I should be compiled and
>> run. I just hope to learn how to start a software in Ada by example.
> I did not checked all of it, but here is a good list of samples (there
> may be some others too):
> http://sandbox.mc.edu/~bennet/ada/examples/

Yes it's a good place for learn Ada from piece of Ada sample code.

>
>> Any suggestions or comments will be really appreciated. Thanks in
>> advance.
> Yes, start with this:
>
>>>>
> -- Hello World, the quick easy form.
>
> with Ada.Text_IO; use Ada.Text_IO;
>
> procedure Hello is
> begin
> Put_Line ("Hello, Bonjour, Ohayo");
> end;
>>>>
>
> Second alternative, for people who enjoy to be more formal or strict:
>
>>>>
> -- Hello World, the proud form (lol).
>
> with Ada.Text_IO;
>
> procedure Hello is
> package IO renames Ada.Text_IO;
> Greeting_Message : constant String := "Hello, Bonjour, Ohayo";
> begin
> IO.Put_Line (Greeting_Message);
> end Hello;
>>>>
>
>> Regards,
>> Jinsong
> Have a nice time Jinsong
>
Thank you very much for your kind help.

Regards,
Jinsong





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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 17:48 ` Niklas Holsti
  2011-10-09 18:37   ` Ludovic Brenta
@ 2011-10-10  6:45   ` Jinsong Zhao
  1 sibling, 0 replies; 14+ messages in thread
From: Jinsong Zhao @ 2011-10-10  6:45 UTC (permalink / raw)


On 2011-10-10 1:48, Niklas Holsti wrote:
> On 11-10-09 18:20 , Jinsong Zhao wrote:
>> Hi there,
>>
>> I am new to Ada, and I just have some experiences in using Fortran.
>
> Welcome, then. May I ask what attracted you to Ada? I am asking partly
> out of curiosity, but also because if you tell us what you hope to gain
> by using Ada, we may better advise you on how to organize your code, and
> on other Ada usage.

At first, I should express my thanks for your kind, detailed, and 
informative reply.

Long time ago, I have read a introductory material about Ada, and know 
it's a excellent programming language. So, I hope to try it, and write 
some small program in numerical computation, for which I used to code in 
Fortran.

>
>> When using Fortran, I generally put each subroutine or function in a
>> separate file, e.g., dot.for for dot product of two vectors. Then a
>> main.for that call the necessary subroutine or functions. It seems to be
>> rational.
>>
>> When I using Ada, I don't know how to do.
>
> If you like, you can do exactly as you are accustomed to doing in
> Fortran (although this would be an unusual style for Ada). You can put
> each Ada function or procedure in its own compilation unit.
>
> The only difference is that you will typically write two files per
> subprogram, one to specify the subprogram (its name, its parameters, and
> its return type, if it is a function) and one to implement the
> subprogram by giving its body, which contains the declarations of the
> local variables and the statements that are executed in the subprogram.
>
> For example, let's make a function that adds two Float numbers and
> returns their sum, and let's call this function Add. In the following, I
> assume you are using the GNAT Ada compiler and its default conventions
> for source file names.
>
> The Add function will have a specification (or declaration) file
> add.ads, which contains this one line:
>
> function Add (A, B : Float) return Float;
>
> Any other subprogram that needs to use (call) the Add function will
> start with the line
>
> with Add;
>
> which makes the compiler read the file add.ads, so that the compiler
> knows the name, parameters, and return type of Add.
>
> The Add function will have an implementation (or body) file add.adb,
> which contains these five lines:
>
> function Add (A, B : Float) return Float
> is
> begin
> return A + B;
> end Add;
>
> Assume that your main subprogram should use Add to compute the sum of
> the numbers 15.6 and 88.2 and print out the sum, and you give this
> procedure the name Main, then you would write it as the file main.adb
> with the following content:
>
> with Add; -- So that we can call Add, below.
> with Ada.Text_IO; -- So that we can call Put_Line, below.
> procedure Main
> is
> begin
> Ada.Text_IO.Put_Line (Float'Image (Add (15.6, 88.2)));
> end Main;
>
> This program thus consists of three files: add.ads, add.adb, main.adb.
> To compile this program with GNAT, you only have to give the command
>
> gnatmake main
>
> and GNAT will compile all three files and create an executable called main.
>
>> There are procedure, function,
>> package, package body, and so on (with different file extension, e.g.,
>> ada, adb, ads, ...). And there is no main program.
>
> The main program is just a parameterless procedure, like the Main above.
> It can be called anything you like; its name usually (but not
> necessarily) becomes the name of the program executable.
>
> The one-subprogram-per-file method shown above, which is what you have
> been doing in Fortran, breaks down when you have subprograms that need
> to access some global data, for example like Fortran COMMON data. If you
> don't want to pass all this data in parameters, you must put it in a
> package. Then you can have two Ada designs, one that is very similar to
> Fortran COMMON, and the other that is more typical for Ada.
>
> Here is how to do the Fortran-like design. Suppose that the Add
> function, above, should also include in the sum the value of a global
> variable Offset, that relates to some "scale" that the program is using,
> but you don't want to pass Offset as a parameter to Add. In Fortran, you
> could declare a COMMON area called Scale, containing a variable called
> Offset. In Ada, this can be implemented as a package Scale with a public
> variable Offset. Such a package is written in one file, scale.ads, as
> follows:
>
> package Scale
> is
> Offset : Float := 0.0;
> end Scale;
>
> Here I also gave the Offset an initial value, just to avoid using an
> undefined value.
>
> The Add function would now be written as follows, in add.adb:
>
> with Scale;
> function Add (A, B : Float) return Float
> is
> begin
> return A + B + Scale.Offset;
> end Add;
>
> Note that:
>
> - the line "with Scale" gives us access to the data in Scale, but
>
> - you still have to use the qualified name, Scale.Offset, to refer
> to the variable Offset in the package Scale.
>
> If you add a line after "with Scale", saying "use Scale", you can use
> just the name Offset instead of Scale.Offset. But many Ada programmers
> think that such "use clauses" should be used very sparingly, and that
> writing Scale.Offset is clearer.
>
> Note that the file add.ads was not changed, since the text in that file
> does not have to refer to the Scale package.
>
> Suppose now that your Main subprogram needs to Add the same two numbers
> as before, but with an Offset of 3.2. This would be written as follows,
> in main.adb:
>
> with Add; -- So that we can call Add, below.
> with Scale; -- So that we can access Scale.Offset, below.
> with Ada.Text_IO; -- So that we can call Put_Line, below.
> procedure Main
> is
> begin
> Scale.Offset := 3.2;
> Ada.Text_IO.Put_Line (Float'Image (Add (15.6, 88.2));
> end Main;
>
>> Would anyone here like to give a an analogy between the source code
>> organization in Fortran and the one in Ada?
>
> The example above was how one would represent Fortran COMMON in Ada
> packages, in a Fortran-like way: write the COMMON area as a package
> (*.ads file) with public variables representing the COMMON data, and
> then "with" this package in any subprogram (*.adb file) that needs to
> use this data.
>
> However, this style is not the typical Ada style. The more common style
> in Ada is to make packages that contain both data and subprograms, and
> to make the data private as far as possible.
>
> This is stretching the above example a bit, but the principle would be
> to put the Add function in the Scale package, since it needs to use
> Scale.Offset, and to move the Offset variable into the package body, so
> that it cannot be accessed from outside the package. The file scale.ads
> would now look like this:
>
> package Scale
> is
> function Add (A, B : Float) return Float;
> procedure Set_Offset (To : in Float);
> end Scale;
>
> The declaration of the Offset variable, and the bodies of the two
> subprograms, would now be written in the "body file" for Scale, which is
> called scale.adb and contains this:
>
> package body Scale
> is
>
> Offset : Float := 0.0;
>
> function Add (A, B : Float) return Float
> is
> begin
> return A + B + Offset;
> end Add;
>
> procedure Set_Offset (To : in Float)
> is
> begin
> Offset := To;
> end Set_Offset;
>
> end Scale;
>
> Of course, the files add.ads and add.adb are now unnecessary, since Add
> is both declared and implemented within package Scale, thus in the files
> scale.ads and scale.adb.
>
> The Main subprogram in main.adb would now have this form:
>
> with Scale; -- So that we can use it, below.
> with Ada.Text_IO; -- So that we can call Put_Line, below.
> procedure Main
> is
> begin
> Scale.Set_Offset (3.2);
> Ada.Text_IO.Put_Line (Float'Image (Scale.Add (15.6, 88.2));
> end Main;
>
> The single command "gnatmake main" is still enough to compile the
> program, although Main now uses other packages.
>
> If you have any other subprograms that are also related to the Scale,
> and need to use Scale.Offset, you would put them in package Scale, too.
>

I think that described in above is a excellent tutorial for a Fortran 
user who hope to learn Ada as a second language. Thank you very much for 
simplifying the complex problem.

> Of course, finding a good package structure can become complex if you
> have something like a Fortran program with several COMMON areas, and
> have several subprograms that use different subsets of the COMMON areas.
> You can fall back on the Fortran-like structure (one package per COMMON
> area, with public data), or look up some texts on "information hiding"
> and "software architecture", but even so, there are usually several ways
> to slice the cake, and the best way is often a matter of taste.

Yes, the programs that I have read in Fortran all have many COMMON 
areas. I will try to learn how to deal with those situation using Ada. 
Of course, your tutors above gave me many help.

>
>> And, please, if you like, point me a small, complete open source
>> software in Ada (not a library or package). I should be compiled ands
>> run. I just hope to learn how to start a software in Ada by example.
>
> Sorry, my internet access at present (on travel) is so wonky that I have
> no web access, in practice.
>

Thanks again!

Regards,
Jinsong



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-09 18:37   ` Ludovic Brenta
  2011-10-09 21:24     ` J-P. Rosen
@ 2011-10-10 12:09     ` Jinsong Zhao
  1 sibling, 0 replies; 14+ messages in thread
From: Jinsong Zhao @ 2011-10-10 12:09 UTC (permalink / raw)


On 2011-10-10 2:37, Ludovic Brenta wrote:
> Niklas Holsti writes on comp.lang.ada:
>> On 11-10-09 18:20 , Jinsong Zhao wrote:
>>> Hi there,
>>>
>>> I am new to Ada, and I just have some experiences in using Fortran.
>>
>> Welcome, then. May I ask what attracted you to Ada? I am asking partly
>> out of curiosity, but also because if you tell us what you hope to
>> gain by using Ada, we may better advise you on how to organize your
>> code, and on other Ada usage.
>
> I am curious, too.
>
>>> When using Fortran, I generally put each subroutine or function in a
>>> separate file, e.g., dot.for for dot product of two vectors. Then a
>>> main.for that call the necessary subroutine or functions. It seems to
>>> be rational.
>
> OK but where do you place variables that are shared by multiple
> subroutines or functions?  Where do you place type declarations?  This
> is quite crucial for my point below.

In Fortran 90 or newer standard, those variables and type declaration 
can be put into module. In Fortran 77, the variable are put into COMMON, 
and block data section.

>
>>> When I using Ada, I don't know how to do.
>
> In addition to the rules of thumb given by others, I'll now explain the
> reasoning behind a proper choice of where to place your subprograms.
> It's all about _visibility_.
>
> package P is
>     -- this part is visible to anyone who says "with P;"
> private
>     -- this part is visible only from the body of P
> end P;
>
> package body P is
>     -- this part is completely hidden
> end P;
>
> procedure Proc is
>     -- this part is completely hidden
> begin
>     -- this part is completely hidden
> end Proc;
>
> A subprogram declared in the package P can see everything in the public
> and private parts of the spec; it can also see everything that has been
> declared above it inside the body.  Thus, a package spec will normally
> look like:
>
> package P is
>     type T is private;
>     procedure Foo (Param : in out T);
> private
>     type T is ...;
> end P;
>
> If several subprograms use the same type T in their specs, then they
> should all be declared in the same package.  So, my advice to you is to
> organize your sources not in terms of subprograms, but in terms of
> types; each major type should be in a package of its own, along with all
> the subprograms that operate on it.  One example that I wrote is here:
>
> http://green.ada-france.org:8081/revision/browse/108fe173864fa16185a547d486849a475dd3c2a3
>
> You will find one main subprogram (test.adb), one spec
> (s_expression.ads) declaring a type T and all subprograms operating on
> it (the type T is private and its details are in the private part of the
> spec), and one package body (s_expression.adb) containing the
> implementation of those subprograms.
>

Thank you very much for your example and advices on visibility.

Regards,
Jinsong



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-10  6:02   ` Jinsong Zhao
@ 2011-10-10 13:15     ` Paul Colin Gloster
  2011-10-10 15:46       ` Simon Wright
                         ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Paul Colin Gloster @ 2011-10-10 13:15 UTC (permalink / raw)


Jinsong Zhao <jszhao@yeah.net> sent on October 10th, 2011:
|-----------------------------------------------------------|
|"[..]                                                      |
|                                                           |
|Oops, I have seen *.ada somewhere, but I don't recall it...|
|                                                           |
|[..]"                                                      |
|-----------------------------------------------------------|

Hi,

That is not a mistake. There are compilers which support *.ada.



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-10 13:15     ` Paul Colin Gloster
@ 2011-10-10 15:46       ` Simon Wright
  2011-10-10 19:03       ` RasikaSrinivasan@gmail.com
  2011-10-10 22:12       ` Randy Brukardt
  2 siblings, 0 replies; 14+ messages in thread
From: Simon Wright @ 2011-10-10 15:46 UTC (permalink / raw)


Paul Colin Gloster <Colin_Paul_Gloster@ACM.org> writes:

> Jinsong Zhao <jszhao@yeah.net> sent on October 10th, 2011:
> |-----------------------------------------------------------|
> |"[..]                                                      |
> |                                                           |
> |Oops, I have seen *.ada somewhere, but I don't recall it...|
> |                                                           |
> |[..]"                                                      |
> |-----------------------------------------------------------|
>
> Hi,
>
> That is not a mistake. There are compilers which support *.ada.

GNAT comes with a tool 'gnatchop' which will split an Ada source file
containing multiple units into the separate files that GNAT expects; and
it makes sense to use .ada for such a file.



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-10 13:15     ` Paul Colin Gloster
  2011-10-10 15:46       ` Simon Wright
@ 2011-10-10 19:03       ` RasikaSrinivasan@gmail.com
  2011-10-10 22:12       ` Randy Brukardt
  2 siblings, 0 replies; 14+ messages in thread
From: RasikaSrinivasan@gmail.com @ 2011-10-10 19:03 UTC (permalink / raw)


On Oct 10, 9:15 am, Paul Colin Gloster <Colin_Paul_Glos...@ACM.org>
wrote:
> Jinsong Zhao <jsz...@yeah.net> sent on October 10th, 2011:
> |-----------------------------------------------------------|
> |"[..]                                                      |
> |                                                           |
> |Oops, I have seen *.ada somewhere, but I don't recall it...|
> |                                                           |
> |[..]"                                                      |
> |-----------------------------------------------------------|
>
> Hi,
>
> That is not a mistake. There are compilers which support *.ada.

Way back when - DEC Ada (on VMS) was around:

conventions were :

Package Specs => *_.ADA
Package Body  => *.ADA

Upon compilation the same sources used to get copied into an Ada
library *.ADC



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

* Re: how to organize source code for a complete software? Thanks!
  2011-10-10 13:15     ` Paul Colin Gloster
  2011-10-10 15:46       ` Simon Wright
  2011-10-10 19:03       ` RasikaSrinivasan@gmail.com
@ 2011-10-10 22:12       ` Randy Brukardt
  2 siblings, 0 replies; 14+ messages in thread
From: Randy Brukardt @ 2011-10-10 22:12 UTC (permalink / raw)


"Paul Colin Gloster" <Colin_Paul_Gloster@ACM.org> wrote in message 
news:alpine.LFD.2.00.1110101413140.20260@localhost.localdomain...
>> Jinsong Zhao <jszhao@yeah.net> sent on October 10th, 2011:
>> Oops, I have seen *.ada somewhere, but I don't recall it...
> That is not a mistake. There are compilers which support *.ada.

Pretty much any Ada compiler will support .ada, as that is the native 
extension of (most of) the ACATS tests. A compiler could rename all of the 
tests, but it is a lot easier to support processing that extension. Other 
ACATS tests use .dep, .a, and .tst -- so most Ada compilers allow arbitrary 
extensions. (The default extensions, important for tools like Gnatmake, are 
a different story, and differ between some compilers.)

                         Randy.





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

end of thread, other threads:[~2011-10-10 22:12 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-09 16:20 how to organize source code for a complete software? Thanks! Jinsong Zhao
2011-10-09 17:16 ` stefan-lucks
2011-10-10  5:52   ` Jinsong Zhao
2011-10-09 17:37 ` Yannick Duchêne (Hibou57)
2011-10-10  6:02   ` Jinsong Zhao
2011-10-10 13:15     ` Paul Colin Gloster
2011-10-10 15:46       ` Simon Wright
2011-10-10 19:03       ` RasikaSrinivasan@gmail.com
2011-10-10 22:12       ` Randy Brukardt
2011-10-09 17:48 ` Niklas Holsti
2011-10-09 18:37   ` Ludovic Brenta
2011-10-09 21:24     ` J-P. Rosen
2011-10-10 12:09     ` Jinsong Zhao
2011-10-10  6:45   ` Jinsong Zhao

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