From: Paul Van Delst on
beliavsky(a)aol.com wrote:
> Paul Van Delst wrote:
>
>>Hello,
>>
>>I'm putting together some coding guidelines for review by folks here and I'm gathering
>>input from a bunch of sources. I want to get some other people's opinions on a particular
>>item.
>>
>>In one set of guidelines regarding USE satements I came across the recommendation to keep
>>USE statements local and not to put them in the module header.
>>
>>This behaviour is the total opposite of what I do - I put all USE statements as the very
>>first statements in modules and /none/ in the module procedures.
>
>
> I follow your practice.
>
>
>>I do so because, in my
>>mind at least if not in practice, each procedure in that module cannot logically reside
>>anywhere else but in that module so it makes no sense to repeat the exact same USE
>>statements throughout. Additionally, I like being able to determine all the module's USE
>>dependencies by looking in one place.
>>
>>So, without trying to start a "my way is better than your way" to-and-fro, do other folks
>>have an opinion? Is there an accepted reason for doing something like keeping USE
>>statements local to procedures?
>
>
> If only one procedure in a module USEs something called "foo" from
> another module, putting the USE inside that procedure would make clear
> that that is the only place "foo" is referenced. If many procedures use
> foo, it is convenient to put the USE at the beginning of the module.

Yes, I thought about that case, but in the end I tend towards consistency. I know that all
the required USE statements will be at the top of the module, evne if only one module
procedure in that module actually uses stuff from the USE modules. It's one less thing for
me to remember.

> On a separate topic, I think USE statements should usually have the
> ONLY clause to clarify dependencies. Have you considered this matter in
> your guidelines?

Yes. Well, ONLY clauses are addressed in several of the sources I'm cribbing from. :o)

And that makes me think of something else. A typical thing to do is read data from file.
The way I generally approach this is to read the file data into a derived type. The
derived type definition (MyType_type) and associated procedures to allocate, destroy,
assign, etc the structure are placed in a module named
MyType_Define.f90
All the I/O routines are placed in a module named, e.g.
MyType_netCDF_IO.f90
for netCDF format file I/O. The I/O module USEs the Define module. In both modules I use
the PRIVATE statement followed by explicit declaration of all public entities.

Now typically, when my code needs to read and play with the MyType data, I do the following:
USE MyType_Define
USE MyType_netCDF_IO

What do people think of making all the public entities of MyType_Define available via
MyType_netCDF_IO so all I would have to do would be
USE MyType_netCDF_IO

to get access to the type definition/procedures along with the I/O functions?

That is, I explicitly declare all the public entities of MyType_Define as public in
MyType_netCDF_IO.

It seems silly, but when I do the latter, I feel unclean.... :o) I would prefer a more
module-structure-related reason arguing for the former method (or disabusing me of it).

cheers,

paulv

--
Paul van Delst
CIMSS @ NOAA/NCEP/EMC
From: Richard Edgar on
Paul Van Delst wrote:

> In one set of guidelines regarding USE satements I came across the
> recommendation to keep USE statements local and not to put them in the
> module header.
>
> This behaviour is the total opposite of what I do - I put all USE
> statements as the very first statements in modules and /none/ in the
> module procedures. I do so because, in my mind at least if not in
> practice, each procedure in that module cannot logically reside anywhere
> else but in that module so it makes no sense to repeat the exact same
> USE statements throughout. Additionally, I like being able to determine
> all the module's USE dependencies by looking in one place.

I follow your way, unless I'm interfacing onto another code (and then, I
usually just have little wrappers which call into code written to my
usual style). If you're going to repeat the same information in each
subprogram, then IMO the 'grouping' idea of modules is being negated.
And you don't even get out of the recompile cascade (currently being
debated elsewhere today).

To help guard against namespace pollution, I make everything PRIVATE by
default. And I really should make more use of ONLY clauses.

Richard
From: Joe Krahn on
Paul Van Delst wrote:
> Hello,
>
> I'm putting together some coding guidelines for review by folks here and
> I'm gathering input from a bunch of sources. I want to get some other
> people's opinions on a particular item.
>
> In one set of guidelines regarding USE satements I came across the
> recommendation to keep USE statements local and not to put them in the
> module header.
>
> This behaviour is the total opposite of what I do - I put all USE
> statements as the very first statements in modules and /none/ in the
> module procedures. I do so because, in my mind at least if not in
> practice, each procedure in that module cannot logically reside anywhere
> else but in that module so it makes no sense to repeat the exact same
> USE statements throughout. Additionally, I like being able to determine
> all the module's USE dependencies by looking in one place.
>
> So, without trying to start a "my way is better than your way"
> to-and-fro, do other folks have an opinion? Is there an accepted reason
> for doing something like keeping USE statements local to procedures?
> Should the localisation of USE statements relate somehow to the module
> structure?
>
> cheers,
>
> paulv
>
I am guessing that the suggestion of individual USE statements goes with
the idea of limiting every name space to the minimum required in every
procedure. I generally think of a module as sharing a common name space.
If procedures vary too much, it could become a bit confusing, and maybe
they don't really belong in the same module.

Another reason (I just thought of) is that people who favor USE within
every procedure probably want to be able to look at the beginning of
every procedure and see a complete list of all entities accessible to
that procedure.

If you want to satisfy both classes of people in the case of code shared
among a group, maybe you can do both. For example, you could require
every USEd module to be listed at the beginning of every module, but
also require procedures to list each individual USE item. (Just an idea
-- the problem is, what to do with a module-level USE statement if no
part is accessed in the modules specification part?)

One thing I think would be nice is to be able to access members of a
module through the module's name without bringing the individual items
into your name space, such as MODULE_NAME%PROCEDURE_NAME(...). Since
MODULE_NAME uses the same name space as variables, that syntax won't
case a conflict (right?). One can then bring commonly used items into
your namespace, but still get at the remaining items.

For now, it might be a reasonable idea to rename less-used module items
by prefixing the module's name, especially if the procedure name is not
very unique.

Joe
From: Keith Refson on
Paul Van Delst wrote:

> In one set of guidelines regarding USE satements I came across the
> recommendation to keep USE statements local and not to put them in the
> module header.

>
> This behaviour is the total opposite of what I do - I put all USE
> statements as the very first statements in modules and /none/ in the
> module procedures. I do so because, in my mind at least if not in
> practice, each procedure in that module cannot logically reside anywhere
> else but in that module so it makes no sense to repeat the exact same
> USE statements throughout. Additionally, I like being able to determine
> all the module's USE dependencies by looking in one place.
>

All the responses to your post concentrate on the programmer efficiency
and maintainability aspects of this choice. Unfortunately there is another,
more practical consideration, which I didn't see mentioned.

In the context of a large multi-module development project it has been my
experience that unshielded USE statements in module headers can cause
compilers to break or misbehave. I have seen several examples with more
than one compiler - one fresh in my memory is that compiling one of our
modules with Intel Fortran 9.0 uses 1.7GB of memory for the compiler process
without optimization. This drops to just over 1GB when a module lower down the
chain is modified, moving unqualified USE statements from the module level
into the subroutine blocks. I have seen worse behaviour with other compilers
-- frequently internal compiler errors, resource limit exhaustion and other
various crashes, which are alleviated by avoiding module-level USE statements.

I'm not 100% sure why this practice should stress a compiler so severely.
One possibility is the sheer size of the namespace. In a project with a
compilation cascade, the upper level modules can end up associating a very
large number of variables. There's also the case as happens in our project
when A uses B and C, but B also uses C. In that case all the public variables
in C are USE associated to A via two separate routes, the direct and the indirect
one. In the general case of multiple USE associations, especially when some have
ONLY qualifications and others do not my guess is that this may cause difficulty
for the compiler in disentangling the web of associations.

Now much of the above explanation is guesswork, and I'd appreciate comments
from those with experience of F95 compiler writing on the accuracy or otherwise
of this guesswork.

Keith Refson

--
Dr Keith Refson,
Building R3
Rutherford Appleton Laboratory
Chilton
Didcot kr AT
Oxfordshire OX11 0QX isise D@T rl D.T ac D?T uk
From: Pierre Asselin on
Paul Van Delst <Paul.vanDelst(a)noaa.gov> wrote:
> beliavsky(a)aol.com wrote:
> >
> > If only one procedure in a module USEs something called "foo" from
> > another module, putting the USE inside that procedure would make clear
> > that that is the only place "foo" is referenced. If many procedures use
> > foo, it is convenient to put the USE at the beginning of the module.

> Yes, I thought about that case, but in the end I tend towards consistency. I know that all
> the required USE statements will be at the top of the module, evne if only one module
> procedure in that module actually uses stuff from the USE modules. It's one less thing for
> me to remember.

On the contrary, you now have to remember what procedures do *not* use what
modules and you have no easy way of cribbing that from the sources. What
happens if one of the lower-level modules is redesigned ? How do you
know what higher-level code needs to be updated ?


> > On a separate topic, I think USE statements should usually have the
> > ONLY clause to clarify dependencies. Have you considered this matter in
> > your guidelines?

> Yes. Well, ONLY clauses are addressed in several of the sources I'm cribbing from. :o)

If you put the use statements at the top of the module, your ONLY clauses have
to be the union of all the ONLYs of individual procedures. Done the other way,
the ONLY clauses are narrow. Which way conveys the most information ?

I would put the use statements in individual procedures, but I would allow
them at module scope if the individual statements would otherwise be
close to identical and more of a PITA than they're worth. Since you
are writing coding standards, you could also mandate a comment at module
level, warning that there are USEs after the CONTAINS.


> And that makes me think of something else.
> [ ... ]
> Now typically, when my code needs to read and play with the MyType data, I do the following:
> USE MyType_Define
> USE MyType_netCDF_IO
>
> What do people think of making all the public entities of MyType_Define available via
> MyType_netCDF_IO so all I would have to do would be
> USE MyType_netCDF_IO

> to get access to the type definition/procedures along with the I/O functions?

The latter, if it logically makes sense to do so. Not sure what to do if
there are several modules that operate on MyType, for example

! do we require USE MyType_Define ?
USE MyType_netCDF_IO
USE MyType_XML_IO ! just an example, okay ?
USE MyType_Operations

but then you should probably

USE MyType_Wrapper_module_for_everything

The rationale is to keep client code from having to USE too many
obscure modules.

Playing Devil's Advocate, in C the tradition is to #include all headers
at file scope and to #include needed headers from headers. Transliterated
to Fortran, that would mean USE at module scope (contrary to what I said)
and single-module wrappers (as I said).


--
pa at panix dot com