Let's say you have a Fortran 90 module containing lots of variables, functions and subroutines. In your USE
statement, which convention do you follow:
- explicitly declare which variables/functions/subroutines you're using with the
, only :
syntax, such asUSE [module_name], only : variable1, variable2, ...
? - Insert a blanket
USE [module_name]
?
On the one hand, the only
clause makes the code a bit more verbose. However, it forces you to repeat yourself in the code and if your module contains lots of variables/functions/subroutines, things begin to look unruly.
Here's an example:
module constants
implicit none
real, parameter :: PI=3.14
real, parameter :: E=2.71828183
integer, parameter :: answer=42
real, parameter :: earthRadiusMeters=6.38e6
end module constants
program test
! Option #1: blanket "use constants"
! use constants
! Option #2: Specify EACH variable you wish to use.
use constants, only : PI,E,answer,earthRadiusMeters
implicit none
write(6,*) "Hello world. Here are some constants:"
write(6,*) PI, &
E, &
answer, &
earthRadiusInMeters
end program test
Update Hopefully someone says something like "Fortran? Just recode it in C#!" so I can down vote you.
Update
I like Tim Whitcomb's answer, which compares Fortran's USE modulename
with Python's from modulename import *
. A topic which has been on Stack Overflow before:
‘import module’ or ‘from module import’
- In an answer, Mark Roddy mentioned:
don't use 'from module import *'. For any reasonable large set of code, if you 'import *' your will likely be cementing it into the module, unable to be removed. This is because it is difficult to determine what items used in the code are coming from 'module', making it east to get to the point where you think you don't use the import anymore but its extremely difficult to be sure.
- In an answer, Mark Roddy mentioned:
What are good rules of thumb for python imports?
- dbr's answer contains
don't do from x import * - it makes your code very hard to understand, as you cannot easily see where a method came from (from x import *; from y import *; my_func() - where is my_func defined?)
- dbr's answer contains
So, I'm leaning towards a consensus of explicitly stating all the items I'm using in a module via
USE modulename, only : var1, var2, ...
And as Stefano Borini mentions,
[if] you have a module so large that you feel compelled to add ONLY, it means that your module is too big. Split it.
I know I'm a little late to the party, but if you're only after a set of constants and not necessarily computed values, you could do like C and create an include file:
inside a file, e.g., constants.for
Edited to remove "real(4)" as some think it is bad practice.
It's a matter of balance.
If you use only a few stuff from the module, it makes sense if you add ONLY, to clearly specify what you are using.
If you use a lot of stuff from the module, specifying ONLY will be followed by a lot of stuff, so it makes less sense. You are basically cherry-picking what you use, but the true fact is that you are dependent on that module as a whole.
However, in the end the best philosophy is this one: if you are concerned about namespace pollution, and you have a module so large that you feel compelled to add ONLY, it means that your module is too big. Split it.
Update: Fortran? just recode it in python ;)
The main advantage of USE, ONLY for me is that it avoids polluting my global namespace with stuff I don't need.
Agreed with most answers previously given,
use ..., only: ...
is the way to go, use types when it makes sense, apply python thinking as much as possible. Another suggestion is to use appropriate naming conventions in your imported module, along withprivate
/public
statements.For instance, the
netcdf
library usesnf90_<some name>
, which limits the namespace pollution on the importer side.similarly, the ncio wrapper to this library uses
nc_<some name>
(nc_read
,nc_write
...).Importantly, with such designs where
use: ..., only: ...
is made less relevant, you'd better control the namespace of the imported module by setting appropriateprivate
/public
attributes in the header, so that a quick look at it will be sufficient for readers to assess which level of "pollution" they are facing. This is basically the same asuse ..., only: ...
, but on the imported module side - thus to be written only once, not at each import).One more thing: as far as object-orientation and python are concerned, a difference in my view is that fortran does not really encourage type-bound procedures, in part because it is a relatively new standard (e.g. not compatible with a number of tools, and less rationally, it is just unusual) and because it breaks handy behavior such as procedure-free derived type copy (
type(mytype) :: t1, t2
andt2 = t1
). That means you often have to import the type and all would-be type-bound procedures, instead of just the class. This alone makes fortran code more verbose compared to python, and practical solutions like a prefix naming convention may come in handy.IMO, the bottom line is: choose your coding style for people who will read it (this includes your later self), as taught by python. The best is the more verbose
use ..., only: ...
at each import, but in some cases a simple naming convention will do it (if you are disciplined enough...).I used to just do
use modulename
- then, as my application grew, I found it more and more difficult to find the source to functions (without turning to grep) - some of the other code floating around the office still uses a one-subroutine-per-file, which has its own set of problems, but it makes it much easier to use a text editor to move through the code and quickly track down what you need.After experiencing this, I've become a convert to using
use
...only
whenever possible. I've also started picking up Python, and view it the same way asfrom modulename import *
. There's a lot of great things that modules give you, but I prefer to keep my global namespace tightly controlled.Not exactly answering the question here, just throwing in another solution that I have found useful in some circumstances, if for whatever reason you don't want to split your module and start to get namespace clashes. You can use derived types to store several namespaces in one module.
If there is some logical grouping of the variables, you can create your own derived type for each group, store an instance of this type in the module and then you can import just the group that you happen to need.
Small example: We have a lot of data some of which is user input and some that is the result of miscellaneous initializations.
Now if a subroutine only uses data from
init
, you import just that:This is definitely not a universally applicable solution, you get some extra verbosity from the derived type syntax and then it will of course barely help if your module is not the
basicdata
sort above, but instead more of aallthestuffivebeenmeaningtosortout
variety. Anyway, I have had some luck in getting code that fits easier into the brain this way.