From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,FREEMAIL_FROM, PLING_QUERY autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,2f6e39a9d25bcd8b X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!proxad.net!feeder1-2.proxad.net!feeder.erje.net!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Jinsong Zhao Newsgroups: comp.lang.ada Subject: Re: how to organize source code for a complete software? Thanks! Date: Mon, 10 Oct 2011 14:45:50 +0800 Organization: A noiseless patient Spider Message-ID: References: <9fe53iFoe7U1@mid.individual.net> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Mon, 10 Oct 2011 06:45:58 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="E9kds4mxpUa8gjsIwoqDZw"; logging-data="32477"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19lX6t+jeYOaxz/JA5L1uTs" User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 In-Reply-To: <9fe53iFoe7U1@mid.individual.net> Cancel-Lock: sha1:bJIVVR/Yw2W/hBALgDVYsaCMS0A= Xref: g2news2.google.com comp.lang.ada:22316 Date: 2011-10-10T14:45:50+08:00 List-Id: 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