Skip to content

Instantly share code, notes, and snippets.

@mp4096
Last active February 24, 2022 02:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mp4096/f23a36e4c0b3a5bdd0ab to your computer and use it in GitHub Desktop.
Save mp4096/f23a36e4c0b3a5bdd0ab to your computer and use it in GitHub Desktop.
Notes on Fortran

Notes on Fortran

These are some initial impressions of Fortran 2008 as seen by a MATLAB person.

Very generally, I would say Fortran is quite similar to MATLAB (I know that it's actually the other way round). Apart from this, here are some language features that I found quite interesting/quirky/nice/annoying (in no particular order):

  • Implicit typing:
    • Implicit typing in Fortran has nothing to do with modern type inference (a-la auto in C++11)! If it is active, the compiler tries to assign types based on variable names. 😱 So it is really necessary to always use implicit none.
  • Array indexing:
    • Can be specified by the programmer, e.g. one can start indexing with 0 or even use negative indices. On the other hand: Prepare to memorise scenarios in which indices are remapped to 1:N by default and a couple of cases when indices remain the same.
    • MATLAB slices are specified as <lower bound> : <step size> : <upper bound>, whereas Fortran uses <lower bound> : <upper bound> : <step size>.
  • Boilerplate code:
    • It is obvious that Fortran requires much, much more auxiliary stuff like variable declarations, procedure specifications and so on. But somehow I feel it is even more than in C/C++.
  • Manual initialisation of n-rank, n > 1, arrays only by reshape 🙀
  • No namespaces:
    • All procedures and variables from an imported module can be used directly, without any prefixes.
    • To avoid naming clashes, one can use only statements to cherry-pick entities or rename them using the => notation.
  • goto can be actually used! 😈
  • Named constructs:
    • Constructs (do, if, select case, block, ...) can be named and referred to explicitly when calling exit.
  • Abstract interfaces:
    • If there is an already defined abstract interface (function/subroutine signature), it cannot be used for a concrete function! I.e. the concrete function must contain the same explicit interface. For me, it's a straight violation of the DRY principle.
  • No closures:
    • Forget about convenient closures as in MATLAB: fun = @(x) SomeOtherFun(a, x, b); or in Python: fun = lambda x : some_other_fun(a, x, b). Closure-like constructs are possible, but cumbersome.
  • Aliasing of dummy variables:
    • Quite an odd issue for me, probably due to lack of C/C++ experience.
  • Both positional and named arguments are supported
  • % operator for accessing structure fields sorry, type components
  • MATLAB false friends:
    • For me as a MATLAB person, this is extremely irritating.
    • Fortran rank != MATLAB rank
    • Fortran shape == MATLAB size
    • Fortran size == MATLAB numel
    • Fortran spread == MATLAB repmat
    • Contrary to MATLAB, most arithmetical operations are element-wise.
  • Persistence of initialised variables
  • Assumed shape vs. assumed size:
    • Functions and subroutines operating on arrays with unknown number of elements can use either assumed shape or assumed size interfaces. The former is more modern and should be generally used. If the input argument is specified as contiguous, there should be almost no performance decrease compared to legacy assumed size interfaces.
    • Don't forget: Assumed shape arguments' indices are automatically remapped. 1:N is used by default.
  • Pointers:
    • Fortran pointers are not the pointers as known from C/C++. For instance, pointer arithmetic is not possible.
    • I'd say Fortran pointers are more like variable names in Python, i.e. references/tags to values in memory.
  • Operator overloading and user-defined operators are pretty cool.
  • Namelist I/O is also very cool. I wish MATLAB had it too.

Programming for performance

Tips for best performance:

  1. Use statically allocated arrays:
    • access them as global variables with subroutines;
    • if not possible, use contiguous, dynamically allocated module variables.
  2. Prefer subroutines to functions.
  3. Ensure that all your data is contiguous in memory.
  4. Rely on do-loops, don't forget that the inner loop iterates over the leftmost index.
  5. Don't use pointers if you don't really need to:
    • not bad per se, but limits the optimisation possibilities for the compiler.

Fortran lingo

Fortran Other languages (esp. MATLAB/Python)
intrinsic built-in
I/O unit I/O stream
internal I/O sprintf, sscanf
formatted I/O ASCII I/O
unformatted I/O binary I/O
stride index step
array rank array dimensionality
processor compiler
parameter constant
type casting conversion
(explicit) interface function signature
dummy argument ~ function argument
derived type composite type / structure
type component structure field
protected attribute n/a (get and set access in the host module, get access outside of it)
mask logical indexing (MATLAB)
save persistent (MATLAB)
elemental element-wise (MATLAB)
generic interface n/a (a very explicit facility for function overloading)
specific specific implementation of an overloaded function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment