comp.lang.ada
 help / color / mirror / Atom feed
From: Jinsong Zhao <jszhao@yeah.net>
Subject: Re: how to organize source code for a complete software? Thanks!
Date: Mon, 10 Oct 2011 14:45:50 +0800
Date: 2011-10-10T14:45:50+08:00	[thread overview]
Message-ID: <j6u4b2$vmt$1@dont-email.me> (raw)
In-Reply-To: <9fe53iFoe7U1@mid.individual.net>

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



      parent reply	other threads:[~2011-10-10  6:45 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 message]
replies disabled

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