In python a statement like this:
from module import function354
makes sense, because Python is an interpreter language and I don't want python to load all 353 other functions.
Fortran has a similar construct:
use module, only : function354
Why would I use this? The compiler creates a *.mod file anyway, compiling all function. Is there any performance advantage (in compile or run time) if I specify an only-statement?
I can see that it might be helpful to avoid naming conflict, but other than that I don't really see the point.
Two main reasons
To avoid name conflicts, as you mention but seem to think unimportant. In a large, complex code anything that helps maintainability is a bonus, so use, only is a useful addition to aid this
It automatically documents where an entity comes from. Given a large, complex code to read for the first time I can almost guarantee you'll be spending time working out what comes from which module, so use, only is a nice feature to aid code readability
You don't just want fast code - as important is maintainability, and more important is correctness!
Disclaimer:
Some people has pointed (correctly) in the comments that use rename => name can be used independently of use, only. Like this:
use module, f354 => function354
I am keeping the answer because it could be useful as complementary information on the use statement for someone that lands here.
Original Answer:
Just for completeness, there is another feature that use, only provides, that is the ability to rename imported names with locally-bound names (only is not needed for this, see disclaimer above).
Like this:
use module, only: f354 => function354
That has proven useful for me in several different scenarios:
Resolve specific name ambiguities when two used modules provide types or functions with the same name.
Example:
use module1, only: m1_init => initialize
use module2, only: m2_init => initialize
Use short names when the original name is too long, too cryptic or when it is used very often in your program.
Example (from fgsl and lapack):
use fgsl, only: stride => fgsl_aux_vector_double_stride ! too long
use lapack, only: solve => dgesvx ! too cryptic
use iso_c_binding, only: i32 => c_int32_t, i64 => c_int64_t ! too frequent
Make it easier to refactor or use conditional compilation / templating:
Example (from Fortran-lang/stdlib):
use iso_fortran_env, only: sp => real32, dp => real64, qp => real128
! If we decide later to use iso_c_binding instead of iso_fortran_env:
! use iso_c_binding, only: sp => c_float, dp => c_double, qp => c_float128
Related
It seems to me that one of the nice features of submodules is that you can create a helper function in a submodule at very little cost to the programmer; you don't trigger a compilation cascade, you don't clutter the namespace or your documentation, and it is immediately clear where that function can and can't be used. They're like nicer versions of private functions.
However, functions in submodules cannot be used. While this is working as intended, it also appears that this prevents the function from being unit tested. Both unit test frameworks that I'm aware of, pFUnit and fruit, require use syntax to operate.
There are some (imho somewhat inelegant) workarounds for the same problem with private functions discussed in How to access private variables in fortran modules?, but none of those solutions appear to work for functions in submodules, at least not without negating all of the benefits of putting those functions in submodules in the first place.
So are there any solutions to this problem?
The primary purpose of introducing the submodule concept was to avoid long recompilation cascades when only a minor non-interface-breaking change had been introduced to a module file. This is done by separating the interface of the procedures and putting them in the parent module and keeping the implementation in the submodule.
Submodules are themselves permitted to have submodules, which is useful for very large
programs. The number of levels of submodules that I have seen typically does not exceed two (that is, a module with submodules that themselves have submodules) but there is no limit. Each module or submodule is the root of a tree whose other nodes are its descendants and have access to it by host association. No other submodules have such access, which is helpful for developing parts of large modules independently. Furthermore, there is no mechanism for accessing anything declared in a submodule from elsewhere – it is effectively private, as you said.
Therefore, in summary, if you need anything from any submodule at any level to be accessed by any other parts of the program, it must be declared in the original parent module of the submodule. There is no other way, as far as I am aware to access anything in any submodule whose interface or declaration is not given in the original parent module.
Once you put the procedure interfaces and variable/type declarations in the parent module, you can use them anywhere in your program, even though the procedure implementations could be buried in submodules of the parent module.
I have little experience with submodules (so not sure if this is useful), but just to extend my comment above...
!! parent_mod.f90 (public things)
module parent_mod
implicit none
type myint_t
integer :: n = 100
contains
procedure :: add, show
endtype
interface
module subroutine add( x )
class(myint_t) :: x
end
module subroutine show( x )
class(myint_t) :: x
end
endinterface
end
!! parent_helper.f90 (private things to be used by parent_impl.f90
!! and possibly by unit tests)
module parent_helper
use parent_mod, only: myint_t
implicit none
contains
subroutine debug_show( x )
type(myint_t) :: x
print *, "debug: x = ", x
end
end
!! parent_impl.f90 (implementation)
submodule (parent_mod) parent_impl
implicit none
contains
module procedure add
x% n = x% n + 1
end
module procedure show
use parent_helper, only: debug_show
call debug_show( x )
end
end
!! main.f90
program main
use parent_mod, only: myint_t
implicit none
type(myint_t) :: a
call a% add()
call a% show() !! 101
call a% add()
call a% show() !! 102
block
use parent_helper
call debug_show( a ) !! 102
endblock
end
!! build
$ gfortran-10 -fcheck=all -Wall -Wextra parent_mod.f90 parent_helper.f90 parent_impl.f90 main.f90
Does this possibly help avoid recompilation of parent_mod.f90 (even when parent_helper or parent_impl are modified)? (And I noticed that the module name "parent" has no meaning here... XD)
Completely apart from the discussions about whether programming languages should be case sensitive or not [1] [2], what would be a good naming convention for languages that are case-insensitive?
Specifically I'm working in Fortran, but most commonly available style guides are for languages that are case sensitive, and thus recommend naming conventions like:
Class/Type names are CapitalizedWords
Method/function names are firstWordNotCapitalized
Variables are lower_case_with_underscores
Constants are ALL_CAPS_WITH_UNDERSCORES
But in case insensitive languages, everything is effectively ALL CAPS, so the only way to legibly have multi-word names is ALL_CAPS_WITH_UNDERSCORES. So is my only option for distinguishing between the "kinds" of names to go back to Hungarian Notation?
Class/Type names are APPENDED_WITH_T
Method/function/subroutine names are APPENDED_WITH_{F or S}
Module names are APPENDED_WITH_M
Variable names are NOT_APPENDED (and constants are just variables)
Name collisions are a major problem in Fortran, since even the name of a module will cause a collision with a variable name, or a derived type name. Is this a case where, even though everyone says Hungarian notation is a bad idea, it makes sense in this instance?
Edit:
As a response to a comment, for example, in a case sensitive language (C++ for example) I'd be able to do something like this:
in a file (i.e. module) called Logger.cc:
class Logger {
Logger(some type, of arguments) {...}
log(some argument) {...}
}
in another file somewhere:
#include "Logger.h"
void aFunctionThatCreatesALogger() {
...
Logger logger = new Logger(with, arguments)
...
}
void functionThatLogs(Logger logger) {
...
logger.log(thing)
...
}
And the equivalent Fortran might look like:
in a file (i.e. module name Logger.f90):
module Logger
type Logger
contains
procedure :: log
end type
contains
type(Logger) function Logger(some, arguments) result(logger)
logger%some = some
logger%arguments = arguments
end function Logger
subroutine log(logger, argument)
class(Logger) :: logger
type(some), intent(in) :: argument
...
end subroutine log
end module Logger
in another file somewhere:
module someModule
use Logger, only: Logger, Logger
contains
subroutine routineThatCreatesALogger()
type(Logger) :: logger
...
logger = Logger(with, arguments)
...
end subroutine routineThatCreatesALogger
subroutine routineThatLogs(logger)
type(Logger), intent(in) :: logger
...
call logger%log(thing)
...
end subroutine routineThatLogs
end module someModule
but of course the name collisions between the module name, the type name, the "constructor" function, and my variable name are all a problem, because Fortran can't tell the difference between case and/or context of use.
I fully understand that any suggestions will be highly subjective, but I'd still like to here if anybody has a better/different suggestion than Hungarian notation.
I'm pretty sure that the major reason for the case variations in naming conventions is to give a hint to the human reader as to what that name denotes, not to avoid name clashes.
So unless your compiler really supports only uppercase names, for the most part you can adopt the usual conventions even in case-insensitive languages.
If name clashing really begins to be a problem, using prefixes or suffixes (the latter are most likely preferable) might be ok, but I wouldn't make it a general, compulsory convention, but just a thing to use when it's needed.
And (especially) if you do indeed use them only occasionaly, it's most likely better to use something self-explanatory rather than single letters or strange acronyms.
Your examples aFunctionThatCreatesALogger or functionThatLogs, if they were meant as name proposals, might actually not be the monstrosity that they seem at first glance (if used occasionally), but I'd argue that it's much better to start with the most relevant term (log), and put the eventual specifiers at the end (e.g. loggerCreatingFunction or loggerFunction).
Whether to use a full, expanded term, an abbreviation/acronym or even a single letter should depend mostly on whether most developers use tools with good auto-completion or not.
But you should always be wary to use these specifiers, it's most likely better to avoid things like that as much as possible.
So if you wrote code which declares names that use them, think thrice before committing it.
Note that I don't know Fortran (but I did work a lot with another case-insensitive language).
I'm pretty sure I'm going to stick with my initial idea. Append _t to type names, and in situations where a module contains something with the same name, append _module to module names. Other than that I'll stick with the common convention:
Class/Type names are CapitalizedWords
Method/function names are firstWordNotCapitalized
Variables are lower_case_with_underscores
Constants are ALL_CAPS_WITH_UNDERSCORES
That should avoid the vast majority of naming collisions and (hopefully) produce readable code.
The above Fortran example would then become:
module Logger_module
type Logger_t
contains
procedure :: log
end type
contains
type(Logger_t) function createLogger(some, arguments) result(logger)
logger%some = some
logger%arguments = arguments
end function createLogger
subroutine log(logger, argument)
class(Logger_t) :: logger
type(some_t), intent(in) :: argument
...
end subroutine log
end module Logger
and
module some_module
use Logger_module, only: Logger_t, createLogger
contains
subroutine routineThatCreatesALogger()
type(Logger_t) :: logger
...
logger = createLogger(with, arguments)
...
end subroutine routineThatCreatesALogger
subroutine routineThatLogs(logger)
type(Logger_t), intent(in) :: logger
...
call logger%log(thing)
...
end subroutine routineThatLogs
end module some_module
Of course this ignores the question as to whether you should use a convention that relies on case in a case insensitive language, but that's the kind of question that really invites opinionated and subjective arguments, so I won't ask it.
Does Fortran have a standard function/keyword equivalent for C assert?
I could not find assert mentioned in Fortran2003 standard I have. I have found few ways how to use pre-processor, but in this answer it is suggested to write own assertions. Is it possible to create such user function/subroutine without using pre-processor?
I expect that these assertions are disabled for release builds.
Conditional compilation has never really caught on in Fortran and there isn't a standard pre-processor. If getting your pre-processor to switch in and out a dummy assert routine isn't something you want to tackle you could ...
Define a global parameter such as:
logical, parameter :: debugging = .true.
If you are of a nervous disposition you could put this into a module and use-associate it into every scope where it is needed; to my mind using a global parameter seems a reasonable approach here.
Then write guarded tests such as
if (debugging) call assert(...)
Once you want to release the code, set the value of debugging to .false. I expect, though I haven't tested this so you may care to, that any current Fortran compiler can remove dead code when it encounters an expression equivalent to
if (.false.) call assert(...)
and that your released code will pay no penalty for a dummy call to an assert routine.
Another approach might be to create a module, let's call it assertions, along these lines:
module assertions
contains
subroutine assert_prd(args)
! declare args
end subroutine
subroutine assert_dbg(args)
! declare args
! now do do some assertion checking and exception raising, etc
end subroutine
end module assertions
You could then rename the subroutines when you use-associate them, such as:
use, non_intrinsic :: assertions, assert=>assert_dbg
and change that to assert=>assert_prd when you want to turn off assertion checking. I suspect though that compilers may not eliminate the call to the empty subroutine entirely and that your production code might pay a small penalty for every assertion it encounters.
Beyond this, see the paper by Arjen Markus that #AlexanderVogt has referred you to.
To my knowledge, there is no such statement or function/subroutine in Standard Fortran. But - as you have said - you can use your own subroutines/function and/or OOP in Fortran to realize this goal. See Arjen Markus' excellent paper on this topic.
For fixed form sources, one can use -fd-lines-as-comments for release builds and -fd-lines-as-code for debug build (Intel Fortran -d-lines)
and use custom assert:
D if (assert_condition) then
D write(*,*) 'assert message'
D call exit(1)
D endif
Is it possible in modern versions of Fortran to pass a kind parameter to a subprogram and to use this to 'cast' variables to this kind? As an example, in the following code I am trying to convert an default integer to an 16-bit integer before printing it.
program mwe
! Could use iso_fortran_env definition of int16, but I am stuck with
! old versions of ifort and gfortran.
! use, intrinsic :: iso_fortran_env, only : int16
implicit none
! 16-bit (short) integer kind.
integer, parameter :: int16 = selected_int_kind(15)
call convert_print(123, int16)
contains
subroutine convert_print(i, ikind)
implicit none
integer, intent(in) :: i
integer, intent(in) :: ikind
print*, int(i, ikind)
end subroutine convert_print
end program mwe
With this example code the Intel Fortran compiler complains that
mwe.f(24): error #6238: An integer constant expression is required in this context. [IKIND]
...
mwe.f(24): error #6683: A kind type parameter must be a compile-time constant [IKIND]
and gfortran complains
'kind' argument of 'int' intrinsic at (1) must be a constant
Using print*, int(i, int16) in place of print*, int(i, ikind) would of course work fine in this case. However, if convert_print were defined in a a module which does not define int16 then this would be useless.
Is there a way of passing a kind parameter as a constant to subprograms?
I have the same problem. I find extremely inconvenient that it is not allowed to pass the kind datatype as an argument to a procedures. In my case, I am writing write a subroutine to just read a matrix from a file and get the object in the data type that I want to. I had to write four different subroutines: ReadMatrix_int8(…), ReadMatrix_int16(…), ReadMatrix_int32(…) and ReadMatrix_int64(…) which are nothing but the same code with one single line different:
integer(kind=xxxx), allocatable, intent(out) :: matrix(:,:)
It would make sense to write only one subroutine and pass xxxx as an argument. If I find any solution I will let you know. But I am afraid that there is no better solution than writing the four subroutines and then writing an interface to create a generic procedure like:
interface ReadMatrix
module procedure ReadMatrix_int8
module procedure ReadMatrix_int16
module procedure ReadMatrix_int32
module procedure ReadMatrix_int64
end interface
As far as I can work out, what I am trying to do is expressly forbidden by the Fortran 2003 standard (PDF, 4.5 MB):
5.1.2.10 PARAMETER attribute
A named constant shall not be referenced unless it has been defined previously in the same statement, defined in a prior statement, or made accessible by use or host association.
Therefore is seems that I need to define a function for each conversion I wish to do, for example:
subroutine print_byte(i)
implicit none
integer, intent(in) :: i
print*, int(i, int8)
end subroutine print_byte
subroutine print_short(i)
implicit none
integer, intent(in) :: i
print*, int(i, int16)
end subroutine print_short
subroutine print_long(i)
implicit none
integer, intent(in) :: i
print*, int(i, int32)
end subroutine print_long
Obviously all of the above will have to be overloaded to accept different kinds of the input argument. This seems like a lot of work to get around not being able to pass a constant, so if someone has a better solution I am keen to see it.
This Intel expert gives an explanation and an elegant solution. I couldn't explain it better. A full cite follows:
"One day while I was wandering the aisles of my local grocery store, a woman beckoned me over to a table and asked if I would like to "try some imported chocolate?" Neatly arrayed on the table were packages of Lindt, Toblerone, and... Ghiradelli? I asked the woman if California had seceded from the Union, as Ghiradelli, despite its Italian name, hails from San Francisco. I suppose that from the vantage point of New Hampshire, California might as well be another country, much as depicted in that famous Saul Steinberg 1976 cover for The New Yorker, "View of the World from 9th Avenue".
(I've been warned that my blogs don't have enough arbitrary links - this should hold 'em for a while.)
Similarly, in Fortran (I'll bet you were wondering when I'd get to that), something can be so near yet seem so far away. A short time ago, I was writing a new module for Intel Visual Fortran to provide declarations for the Win32 Process Status API. This would contain declarations of types and constants as well as interface blocks for the API routines, some of which take arguments of the new type. The natural inclination is to write something like this:
MODULE psapi
TYPE sometype
some component
END TYPE sometype
INTERFACE
FUNCTION newroutine (arg)
INTEGER :: newroutine
TYPE (sometype) :: arg
END FUNCTION newroutine
END INTERFACE
END MODULE psapi
If you did and compiled it, you'd get an error that type sometype is undefined in the declaration of arg. "What? It's not undeclared, I can see it right above in the same module!" Well, yes and no. Yes, it's declared in the module and could be used anywhere in the module, except.. Except in interface blocks!
The problem is that interface blocks are a "window into the external routine" - they essentially duplicate the declarations you would see in the actual external routine, assuming that routine were written in Fortran. As such, they do not "host associate" any symbols from the enclosing scoping unit (the module in this case.)
In Fortran 90 and Fortran 95, the typical solution for this was to create a separate module, say, "psapi_types", containing all of the types and constants to be used, You'd then add a USE statement inside each function, just as you would have to in the hypothetical external routine written in Fortran. (If it were written in Fortran, the Doctor would slap your wrist with a wet punchcard and tell you to make the routine a module procedure, and then you wouldn't need to worry about this nonsense.) So you would end up with something like this:
MODULE psapi
USE psapi_types ! This is for the benefit of users of module psapi
INTERFACE
FUNCTION newroutine (arg)
USE psapi_types
INTEGER :: newroutine
TYPE (sometype) :: arg
...
Those of you who use Intel Visual Fortran know that in fact there's a giant module IFWINTY for this purpose, containing all of the types and constants for the other Win32 APIs. It's messy and inelegant, but that's what you have to do. Until now...
Fortran 2003 attempts to restore some elegance to this sorry situation, but to preserve compatibility with older sources, it couldn't just declare that interface blocks participate in host association. Instead, a new statement was created, IMPORT. IMPORT is allowed to appear in interface blocks only and it tells the compiler to import names visible in the host scope.
IMPORT is placed following any USE statements but before any IMPLICIT statements in an interface body (the FUNCTION or SUBROUTINE declaration). IMPORT can have an optional import-name-list, much like USE. Without one, all entities accessible in the host become visible inside the interface body. With a list, only the named entities are visible.
With IMPORT, my PSAPI module can look like the first example with the following change:
...
FUNCTION newroutine (arg)
IMPORT
INTEGER :: newroutine
TYPE(sometype) :: arg
...
I could, if I wanted to, use:
IMPORT :: sometype
to say that I wanted only that one name imported. Nice and neat and all in one module!
"But why are you telling me this?", you might ask, "That's a Fortran 2003 feature and Intel Fortran doesn't yet do all of Fortran 2003." True enough, but we keep adding more and more F2003 features to the compiler and IMPORT made it in back in August! So if you are keeping reasonbly current, you can now IMPORT to your heart's content and do away with the mess of a separate module for your types and constants.
If you want to know what other F2003 goodies are available to you, just check the Release Notes for each update. A full list of supported F2003 features is in each issue. Collect 'em all!"
I want to solve a differential equation lots of times for different parameters. It is more complicated than this, but for the sake of clarity let's say the ODE is y'(x) = (y+a)*x with y(0) = 0 and I want y(1). I picked the dverk algorithm from netlib for solving the ODE and it expects the function on the right hand side to be of a certain form. Now what I did with the Intel Fortran compiler is the following (simplified):
subroutine f(x,a,ans)
implicite none
double precision f,a,ans,y,tol,c(24),w(9)
...
call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)
...
contains
subroutine faux(n,xx,yy,yprime)
implicite none
integer n
double precision xx,yy(n),yprime(n)
yprime(1) = (yy(1)+a)*xx
end subroutine faux
end subroutine f
This works just fine with ifort, the sub-subroutine faux sees the parameter a and everything works as expected. But I'd like the code to be compatible with gfortran, and with this compiler I get the following error message:
Error: Internal procedure 'faux' is not allowed as an actual argument at (1)
I need to have the faux routine inside f, or else I don't know how to tell it the value of a, because I can't change the list of parameters, since this is what the dverk routine expects.
I would like to keep the dverk routine and understand how to solve this specific problem without a workaround, since I feel it will become important again when I need to integrate a parameterized function with different integrators.
You could put this all in a module, and make a a global module variable. Make faux a module procedure. That way, it has access to a.
module ode_module
double precision::a
contains
subroutine f(x,a,ans)
implicit none
double precision f,ans,y,tol,c(24),w(9)
call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)
end subroutine
subroutine faux(n,xx,yy,yprime)
implicite none
integer n
double precision xx,yy(n),yprime(n)
yprime(1) = (yy(1)+a)*xx
end subroutine faux
end module
You can check here which compilers support this F2008 feature:
http://fortranwiki.org/fortran/show/Fortran+2008+status
On that page, search for "Internal procedure as an actual argument" .
Passing an internal procedure is allowed by Fortran 2008. That means that your code is correct Fortran and just a more recent compiler is needed.
At the time when this question was posted the support for that in existing compilers was patchy. Some did support it, some did not. This changed considerably and at the time of writing this revision of the answer one can normally use it without needing to think about compiler support any more.
You are not limited to sharing the data in a module. You just have to make sure, that the containing procedure is still running. It is not possible to save the pointer and make a so called 'closure' known from LISP and many modern languages. In languages like Fortran or C the enclosing environment for future calls is not saved and pointers to internal functions become invalid.
The advantage of internal procedure over module procedure is that you can share the data without sharing it in the whole module.
It works well will reasonably old versions of GCC (gfortran), Intel Fortran and Cray Fortran (personally tested) and possibly others. I remember not being able to compile by PGI and Oracle Fortran. As shown by Daniel, it can be checked at http://fortranwiki.org/fortran/show/Fortran+2008+status (search Internal procedure as an actual argument). The most recent version of this table is periodically published in ACM SIGPLAN Fortran Forum.
There is some interesting info in this article https://stevelionel.com/drfortran/2009/09/02/doctor-fortran-in-think-thank-thunk/
Be aware that the implementation of this feature normally requires executable stack due to the use of trampolines. One does not normally think about that but if the OS forbids executable stack, the executable might fail (there were issues in initial versions of Windows Subsystem for Linux, for example).