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 useimplicit none
.
- Implicit typing in Fortran has nothing to do with modern type inference (a-la
- 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 to1: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>
.
- Can be specified by the programmer, e.g. one can start indexing with
- 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 byreshape
🙀 - 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 callingexit
.
- Constructs (
- 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.
- Forget about convenient closures as in MATLAB:
- 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 accessingstructure fieldssorry, type components- MATLAB false friends:
- For me as a MATLAB person, this is extremely irritating.
- Fortran
rank
!= MATLABrank
- Fortran
shape
== MATLABsize
- Fortran
size
== MATLABnumel
- Fortran
spread
== MATLABrepmat
- 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.
- 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
- 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.
Tips for best performance:
- Use statically allocated arrays:
- access them as global variables with subroutines;
- if not possible, use contiguous, dynamically allocated module variables.
- Prefer subroutines to functions.
- Ensure that all your data is contiguous in memory.
- Rely on
do
-loops, don't forget that the inner loop iterates over the leftmost index. - Don't use pointers if you don't really need to:
- not bad per se, but limits the optimisation possibilities for the compiler.
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 |