Re: Program organization



"jiho" <jo.irisson@xxxxxxxxx> wrote in message news:cf3ca77f-1fd9-40f2-b067-b9f433e4a391@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hello everyone,

I am writing code for a spatial model (of fish larvae dispersal in
case you were wondering) and I have a hard time finding a good
organization for it (and I am a biologist, not a comp sci major). I
read bits and pieces in tutorials and on this group's archives but I
would welcome general advice/pointers on the subject. I am looking for
very formal directives, even if they may seem to be restrictive at
first: I need to structure my mind with strict rules before
considering breaking them.

I just found this message a few minutes ago. You may find some of my ideas useful, even though others have already replied.

I agree with your general approach. In my own work, I tend to use a formal, highly disciplined, and highly structured approach in software construction. Sometimes this approach has offended workplace colleagues.

A lot of my practices have been heavily influenced by the two editions of Steve McConnell's Code Complete: A Practical Handbook of Software Contruction. There is a lot of good and useful advice in both editions, even though Steve McConnell has a decidedly negative view of Fortran in the 1st edition and the examples in the 2nd edition are heavily oriented toward the Microsoft Visual Studio languages.
1st edition, ISBN 1-55615-484-4
2nd edition, ISBN 0-7356-1967-0
If you have the time, I strongly recommend that you get both editions and read them.

More precisely, my issue is the following. The only fortran I have
been exposed to is F77 style code, with basically all variables in a
common block which is then inserted everywhere, the main is a
succession of calls to subroutines, each working with the output of
the previous one, and all other files define one of the subroutines.
I don't like the common block approach (since it makes you jump around
to find out what variable names correspond to) and overall this style
seems to be considered bad programming practice.

Yes, FORTRAN 77 is outmoded and does not allow you to make ue of more modern and effetive software development practices. FWIW, here are the dates of the various Fortran standards.
FORTRAN 66 - 1966 - 41 years ago
FORTRAN 77 - 1978 - 29 years ago
Fortran 90 - 1991 - 16 years ago
Fortran 95 - 1997 - 10 years ago
Fortran 2003 - 2004 - 3 years ago

So I tried to divide my code in modules, which seem the way to go for
F90-95 style, depending on their real-life meaning (particle
advection, feeding etc.) and to provide custom data types and small
functions within these modules (since I am more used to the function
than to the subroutine syntax).

Yes. Modular decomposition is a very powerful and effective practice in software engineering. It is a standard practice that is taught in System Analysis and Design courses in Computer Science and Information Systems departments. It allows you to model the source code according to the organization of your real-world problem. Modular decomposition allows you to implement the Software Primary Technical Imperative, which is to Manage Complexity. Using modules also allows you to program in the problem domain much of the time, rather than the computer science domain.

In modular decompostion, you subdivide the problem repeatedly until the module is small enough to understand in itself. One important point: All of the modules that do not use other modules must be completely self-contained; they cannot include references to any data objects or procedures outside of themselves.

But some variables, such as the domain dimensions, indexes, I/O files
handles etc., are needed everywhere and it was therefore most
convenient to define them in a module and include it where needed
(i.e. everywhere :-/ ). The process itself is naturally very linear:
set up a domain, start a loop on time, at each step of the loop
perform the same actions (advect particles, make them feed, make them
die), end the loop, wrap output files and exit. So putting pieces of
code in other files just added extra work to pass the appropriate
variables and to write a correct Makefile but did not add much in
itself. In the end, I got the very structure I was trying to avoid,
with the added overhead of managing modules which look more
complicated that the "one subroutine per file" organization.

You talk about two separate issues here, global data and source code file organization.

Global Data. Computer Science purists often disparage the use of global data. However, there often are legitimate reasons to use global data. One of the most important is data that is conceptually part of the entire program. Therefore, don't be reluctant to use global data when it is really needed. In modern Fortran, you should develop a module that holds the global data and use that module everywhere it is needed. Make sure that everything in that module has the SAVE attribute.

Source Code File Organization. This is really a matter of what you need to do in order to keep the organization of the program clear in your own mind. The Fortran standard does not require any kind of organization regarding procedures and files. You can put everything into one humongous file, put each procedure into a separate file, or somewhere in between. However, most Fortran compilers require that the entire contents of a module need to be in a single file.

My recommendation: Use modules and use one module per file. This is my usual practice.

To turn all this in specific questions:
- are subroutine-files really evil?
- are there intrinsic reasons to prefer functions to subroutines or
are they just two equivalent syntaxes?

No, subroutines are not really evil. Most modern languages muddy the difference between functions and subroutines. In Fortran, almost anything you can do in a subroutine you also can do in a function. In C and C++, a subroutine is called a voide function.

The traditional distinction is that a function is supposed to compute and return a value and a subroutine performs an operation. If you follow this model, most functions will tend to be fairly small whereas most subroutines will be larger and more complex. I tend to be fairly rigorous about this distinction in my own work.

This distinction has implications for naming conventions for functions and subroutines. Function names should describe the result that is returned, e.g., cos() and tan(). Subroutine names should describe the operation that is performed. Usually, this is a strong verb followed by a direct object, Print_Summary_Report, Calc_Current_Positions. In few cases, the verb is obvious, so you do not need to include it in the name. In a Aroudn 10 years ago, I did major rework of an engineering design program. During the rework, I moved the engineering calculations from the main program into subroutines. I called them Coarse_Grid_Analysis, Fine_Grid_Analysis, and Final_Chamber_Design. In this case, it ws not necessary to include the verb.

- if I have a piece of code which performs a linear sequence of
actions on some objects and returns them (basically a just a chuck of
the natural flow of the code), but that I need to call it at several
places, where is it best suited: in the 'contains' part of the main
program, in a file of its own, in a module?

Definitely put the commonly used procedures into one or more modules. Do not put them after the "Contains" statement.

The "Contains" statement does two very different things.
1. In modules, it separates module procedures from module data.
2. In procedures, it separates internal procedures from their host.

If you put it after the "Contains" statement in the main program, then your procedure will be an internal procedure to the main program and will be visible only to the main program. It will not be visible to any other procedure in your program. This is a general property of internal procedures. Internal procedures are visible only to their host procedure. In contrast, module procedures are visible to all procedures that use the module, unless the module procedures are marked "Private".

Eventually, does someone have some code (if possible resembling the
kind of thing I am trying to do) that he/she considers clean and
convenient enough to work with to show me, as an example
(confidentiality assured)?

Thank you very much in advance for your help. Sincerely,

JiHO

Hope this helps. Comments and constructive criticism are welcome.

--
Craig Dedo
17130 W. Burleigh Place
P. O. Box 423
Brookfield, WI 53008-0423
Voice: (262) 783-5869
Fax: (262) 783-5928
Mobile: (414) 412-5869
E-mail: <cdedo@xxxxxxxxx> or <craig@xxxxxxxxxx>

.



Relevant Pages

  • Re: Strange Fortran version
    ... "ENTRY lable" was common in some Fortran IV subroutines and probably ... Fortran compilers (many were written as a higher exercise in M.SC tasks ...
    (comp.lang.fortran)
  • Re: Functions vs. Subroutines
    ... >>and that Fortran programmers would benefit ... > advantages on behalf of the subroutines over the functions. ... y is uninitialized at this point and elide the temp and the copy. ... > just because of the memory leakage. ...
    (comp.lang.fortran)
  • Re: [Question:]How to split one file into 3/4 using fortran?
    ... > If I wrote one it would be in AWK. ... SUBROUTINEs with no dummies and thus no paren but trailing spaces. ... in Fortran identifiers, while the underlying OS might ... identifiers longer than are allowed for filenames. ...
    (comp.lang.fortran)
  • Re: How can I simply use (old) routines?
    ... Whether or not subroutines do have a "type" depends on which way you ... If you actually say IMPLICIT NONE, ... Fortran too can do overloading to some extent, ... that implicit interfaces are disallowed; ...
    (comp.lang.fortran)
  • Re: Basic question on local variable
    ... Fortran they are only allowed for SUBROUTINES. ... The issue usually isn't "is F a PURE function ... no deficiencies and the other way is to make it so complicated ...
    (comp.lang.fortran)