I enjoyed modern Fortran

thumbnail

An exercise on its own rather than a conscious future career choice. This is a short sentence describing my recent venture into Fortran. The language has been on my to learn list for many, many years, but Fortran requires a particular type of problem. The first version of Fortran, the first high-level programming language, appeared in 1957. Fortran is still in active development, it has seen several iterations over the decades. Fortran is the oldest, actively maintained programming language in use today.

Fortran has its niche in scientific computing. Weather simulation, oceanographic simulations, aerospace, automotive, high-performance computing, finance. Anywhere where there’s a need to process vast arrays of numbers, most likely in parallel—that’s where you’ll find Fortran code. The main reasons for this:

  • Array-oriented operations, for example, multiply every array element by two: [10, 20, 45, 65] * 2. Or, multiply one array over another: [10, 30, 46, 32] * [100, 134, 32, 87].
  • Multi-dimensional arrays: up to 15 dimensions out of the box with a short syntax to declare them. For example: real(8) :: var_name(10:20:30).
  • Parallel computing: Fortran coarrays are a relatively simple mechanism to distribute work across CPUs, pin work to selected CPUs, and synchronize the computation across CPUs. Potentially thousands of them.

However, Fortran isn’t a tool you’d apply in a modern microservice architecture. It lacks any networking capabilities, there are no operations on byte arrays, no sockets, no TCP, numbers overflow, so one has to be rather careful, and so on. It’s possible to use C interoperability to bolt sockets on, but that doesn’t feel like Fortran anymore.

Fortran provides logical values (booleans), integers, reals, complex numbers, and characters (a string). Modern Fortran provides derived types, which can be compared to structures or records in other languages. Those can be used to construct class-like structures with methods operating on an internal state of the type.

Finding a reasonable problem for Fortran outside its scientific niche requires an open mind. It is definitely a command line application doing some sort of number crunching with a sprinkle of command line output. I was recently diving into the formulas required to calculate German salary social contributions for employers, as in, the total cost of an employee for a given gross salary. This sounded like a relatively applicable problem.

So, what does the Fortran ecosystem look like today?

While working on my German salary calculator[1], I had the chance to explore the ecosystem and use some cool language features. Starting a new Fortran application is very easy. On macOS, gcc comes with GFortran compiler. The Fortran community built and maintains a tool called FPM, the Fortran Package Manager[2]. FPM is modeled after Rust’s cargo, and it is written in Fortran itself. FPM allows:

  • Creating a new Fortran application.
  • Link and compile an application. This eliminates the need to maintain tedious Makefiles for linking complex programs.
  • Manage application dependencies. Dependencies can be pulled directly from Git remotes, it’s possible to work with tags and branches.
  • Run unit tests.

There are some very interesting libraries to help write decent, modern, compact programs. The most notable ones:

  • FLAP[3]: a command line argument parser.
  • stdlib[4]: an implementation of a standard library for Fortran as the language does not have one.
  • neural-fortran[5]: a microframework for building parallel neural nets.
  • functional-fortran[6]: Functional programming for modern Fortran.

There are, of course, dozens of algorithm implementations to choose from.

I used Visual Studio Code to write my simple program. The community doesn’t let you hang here. There are extensions for many editors providing syntax highlighting. I went for an extension called Modern Fortran[7]. Besides extensions, there is a Fortran language server enabling code suggestions and inline error notifications. I must admit, the ecosystem is very impressive and makes picking up Fortran a fun and straightforward task.

I have experienced the following firsthand:

  • FPM makes it easy to create and manage a program.
  • Handling command line arguments is easy with FLAP.
  • Fortran’s syntax is verbose but easy to read.
  • Modules allow for easy logic encapsulation. Modules make code portable between programs.
  • Derived types are like classes. These can be used to manage an object-local state. It’s possible to have private or public properties, functions, and subroutines.
  • The language is extensible. It’s possible to create custom operators and override existing ones.
  • Fortran provides a mechanism to write generic code.
  • Derived types support inheritance.
  • Programs compile to native binaries.
  • Functions and subroutines can be pure (no side effects). These are verified by the compiler and serve as a hint that they can be executed in parallel.
  • Working with modular code is easy. Fortran supports selective module member usage (like import in other languages).

There are other features that I haven’t had a chance to use, but I learned about them:

  • Previously mentioned array-oriented operations. My program does not need to calculate more than one salary breakdown, so I haven’t needed those.
  • Elementary procedures. Such procedures accept a scalar argument but can be applied to an array.
  • Fortran arrays have no limitations of lower index. Virtually every other programming language comes with zero- or one-indexed arrays. Arrays in Fortran can be arbitrarily indexed. For example, the lower index can be -10. Fortran has lbound(array) and ubound(array) functions for fetching lower and upper array bounds. These, of course, support multiple dimensions. By the way, Fortran arrays are one-indexed by default.
  • coarrays: my program doesn’t need parallel, multi-CPU processing, so I haven’t looked at these in detail, but from what I have seen, these can serve as a poor man’s plane for a multi-CPU actor-like processing framework.
  • Teams, events, and collectives: an abstraction over coarrays enabling easier parallel development.

Would I use Fortran today for a new application? It depends. If I ever have to work on multi-dimensional data, I will consider pulling it into my toolbox.

I enjoyed modern Fortran because:

  • It made me grateful for all the modern programming languages. So you don’t like how Go handles errors? You don’t like arrow functions in modern JavaScript? Or maybe you don’t like C# verbosity? Who cares, it’s a tool for the job. Try Fortran, and you will appreciate how good we have it today.
  • But it’s not as bad as I make it sound. Diving into the longest-maintained programming language was a great way to observe how much modern languages are influenced by the concepts developed 60 years ago.
  • I can confidently pick up old Fortran code and understand what’s happening. For sure, Fortran77 or Fortran90 will be even more verbose than what I have written so far, but the general concept is the same. Considering that Fortran has its stronghold in many, many places and is not going anywhere, it’s a skill worth having.

As a final note, during my learning, I supported myself with the Modern Fortran book written by Milan Curcic[8], and I can’t recommend it enough. The book is easy to follow and comes with fun examples and exercises. If you, like me, would like to dive deeper into Fortran, make sure you get your hands on a copy.