A Gentle Introduction To Fortran

Originally known as FORTRAN, but written in lower case since the 1990s with Fortran 90, this language was developed initially by John Backus as a way to make writing programs for the IBM 704 mainframe easier. The 704 was a 1954 mainframe with the honor of being the first mass-produced computer that supported hardware-based floating point calculations. This functionality opened it up to a whole new dimension of scientific computing, with use by Bell Labs, US national laboratories, NACA (later NASA), and many universities.

Much of this work involved turning equations for fluid dynamics and similar into programs that could be run on mainframes like the 704. This translating of formulas used to be done tediously in assembly languages before Backus’ Formula Translator (FORTRAN) was introduced to remove most of this tedium. With it, engineers and physicists could focus on doing their work and generating results rather than deal with the minutiae of assembly code. Decades later, this is still what Fortran is used for today, as a domain-specific language (DSL) for scientific computing and related fields.

In this introduction to Fortran 90 and its later updates we will be looking at what exactly it is that makes Fortran still such a good choice today, as well as how to get started with it.

Modern Fortran

Punch card from a typical FORTRAN program by the early 1970s. (Credit: Arnold Reinhold, Wikimedia)
Punch card from a typical FORTRAN program by the early 1970s. (Credit: Arnold Reinhold, Wikimedia)

The release of the Fortran 90 (F90) specification in 1991 was the first major update to the language since Fortran 77, and introduced many usability improvements, as well as the dropping of punch card era legacy requirements and limitations to variable lengths and more. This is the reason for our focus on F90 here, as there is no real reason to use F77 or earlier, unless you’re maintaining a legacy codebase, or you have a stack of new cards that need punching. In case you are dying to know what changed, the Wikibooks Fortran Examples article has examples of early FORTRAN all the way to modern Fortran.

Of note here is that a modern Fortran compiler like GCC’s GFortran (forked from g95) still supports F77, but users are highly encouraged to move on to Fortran 95, a minor update to F90, with GFortran supporting up to F2008, with coarray support, as covered later. F2018 support is still a work in progress as of writing, but many features are already available.

Support for the latest standard (F2023) is not widely available yet outside of commercial compilers, but as a minor extension of F2018 it should eventually get rolled into those features as the implementation progresses. This means that for now F2008 is the latest standard we can reliably target across toolchains with new Fortran code.

Beyond GFortran there are a few more options, including Flang in LLVM and LFortran in addition to a gaggle of commercial offerings. Unless you intend to run high-performance computing code on massive parallel clusters like supercomputers, the GNU and LLVM offerings will probably suffice. Simply fetch either GFortran or Flang from your local package manager or equivalent and you should be ready to start with programming in Fortran.

Hello World

As with most DSLs, there is very little preamble to start writing the business logic. The ‘Hello World’ example is most succinct:

program helloworld
    print *, "Hello, World!"
end program helloworld

The program name is specified right after the opening program keyword, which is repeated after the closing end program. This is similar to languages like Ada and Pascal. The program name does not have to match the name of the file. Although there’s no explicit specification for what the file extension has to be for a Fortran source file, convention dictates that for F77 and older you use .f or .for, while F90 and newer uses generally .f90 as extension. Although some opt to use extensions like .f95 and .f03, this is rather confusing, isn’t recognized by all compilers and all of those are similar free-form Fortran source files anyway.

Tl;dr: Use .f90 for modern Fortran source files. Our Hello World example goes into a file called hello_world.f90.

The other point of note in this basic example is the print command, which looks somewhat cryptic but is quite easy. The first argument is the format, reminiscent of C’s printf. The asterisk here simply means that we use the default format for the provided value, but we could for example print the first string as an 11 character wide field and a variable string as 8 wide:

character(len=8) :: name = 'Karl'
print '(a11,a8)', 'My name is ', name

This also shows how to declare and define a variable in Fortran. Note that if you do not start the code with implicit none,  variable names that start with I through N are considered to be integer type and real otherwise. With gfortran you can also globally do this by compiling with the -fimplicit-none flag.

A total of five basic types are supported:

  • real
  • integer
  • logical (boolean)
  • complex
  • character

Finally, comments in Fortran are preceded by an exclamation mark !. It’s also relevant to note that Fortran – like all good programming languages – is case insensitive, so you can still write your Fortran code like it’s F77 or Fortran II, yelling in all caps without anyone but the people reading your code batting an eye.

Hello Science

Now that we have got a handle on the basics of Fortran, we can look at some fun stuff that Fortran makes really easy. Perhaps unsurprisingly, as a DSL that targets scientific computing, much of this fun stuff focuses around making such types of computing as easy as possible. Much of this can be found in the intrinsic procedures of Fortran, which make working with real, integer and complex values quite straightforward.

For example, conjugating a complex number with conjg:

Complex conjugation example in Fortran. (Credit: Fortran Wiki)
(Credit: Fortran Wiki)

Basically, whatever mathematical operation you wish to perform, Fortran should have you covered, allowing you to translate your formulas into a functional program without having to bother with any dependencies or the like. This includes working with matrices and getting into the weeds with numerical precision.

Even better is that you’re not stuck running your code on a single CPU core either. Since Fortran 2008, Coarray Fortran (CAF) is now part of the specification. This feature enables parallel processing, which is generally implementing on top of the Message Passing Interface (MPI) protocol, with gfortran implementing CAF support. Depending on the selected option with the -fcoarray= flag, gfortran can use the ‘single’ image (thread) option, or with a library like OpenCoarrays it can use MPI, GASNet, and others.

When using CAF with MPI, the program (‘image’) is distributed across all nodes in the MPI cluster per its configuration, with synchronization occurring as defined by the program. With OpenCoarrays available from many local OS repositories, this means that any budding molecular scientist and astrophysicists can set up their own MPI cluster and start running simulations with relatively very little effort.

The DSL Life

Much like when we looked at COBOL, a DSL like Fortran is often misunderstood as ‘yet another programming language’, much like how in the 1980s some thought that the scientific and engineering communities were going to switch over to Pascal or Modula-2. One simple reason that didn’t happen lies in the very nature of DSLs, with them being developed explicitly to deal with that specific domain. It will always be possible to do everything a DSL does in any generic programming language, it’s just that a DSL can be optimized more exactly, and is often easier to maintain, since it is not generic.

There are many things that Fortran does not have to concern itself with, yet which haunt languages like C and its kin. Meanwhile, reimplementing Fortran in C would come at considerable cost, run into certain limitations of the language and potentially require compromises in order to get close to the original functionality of the DSL.

Running a cluster with Coarray-based Fortran source, churning through complex simulations that require utmost control over precision and where one small flaw can waste days of very expensive calculations, those are the kind of scenarios where you’re not looking for some generic language to poorly reinvent the wheel, but where you keep using the same – yet much more refined – wheel that has gotten us this far.

11 thoughts on “A Gentle Introduction To Fortran

  1. Fortran has a unique language feature.

    The calculated GOTO.

    As in GOTO intvar
    Where intvar contains a linenumber.

    For some reason, nobody takes my requests to add a calculated COMEFROM to the language seriously.

    They should at least add the calculated goto to rust.
    That and adding support for self modifying code.

    What kind of nerfed language won’t let you self modify the code?
    It’s no wonder the kids just said ‘F it, we’re using JS for everything!’

    Thought…
    Can JS get access the a site’s JS via the DOM and self modify the code?

    Node.js really should contain at least one piece of self modifying code, just for completeness of the pig Fing.

    I digress.

    1. fwiw the proper C mechanism for calculated goto is switch/case. many compilers also allow you to save &&label into a void*var; and do goto *var;, which you could combine with an array of pointers to achieve the same effect. switch/case is better.

      1. Lacks the simple elegance of Goto linenum.

        Won’t see such gems as:
        NextIterEntryPt = NextIterEntryPt + recalcHydroShadowPrices
        NextIterEntryPt = NextIterEntryPt + recalcPipelines

        Which of course requires a bunch of code to sit at magic linenumbers.

        And as they hadn’t had the sense to make each offset a power of 2, they had no way of checking if any of the offsets were already added to NextIterEntryPt.

        Of course the right way was just booleans and code at the top of the loop that does the right recalcs.

        Technical debt.
        What can you say about applied math Phds?
        For sure, never let them design databases.

        Yes, I saw this in the real world on real code, likely used by some of your local utilities to forecast grid operations.
        I should have gotten out of there even sooner.

  2. Fortran makes me facepalm. It’s as verbose as Python, yet with all the issues that are also present in C++.

    If you need to do university-level math then MATLAB can be 🏴‍☠️downloaded🏴‍☠️ for free from the 🕸 and it also has Simulink. If you need direct-to-machine code then it’s easier to just use C++. For graphical stuff nowdays there’s choice: UE5, Unity etc.

    1. With the difference that Matlab is interpreted and very slow compared to compiled Fortran. Matlab is good to proof the math but the heavy lifting should be definitely done by Fortran. With ATLAS instead of BLAS. It becomes up to 100x faster than Matlab. Had to do all that in grad school. Oh, and nothing wrong with verbose, can read a code from 1970 easy enough.

  3. FORTRAN, used in EE university for a few courses – actually had a few advantages over the usual languages.
    For highly controlled print formats, doing numerical analysis, massive equations – it’s great for that.
    But I always blew the stack, one mistake with a missing/extra parameter and it craters. It does crash hard.

  4. I have no desire to go back to fortran again. Fortran IV was my first actual language (360 assembly, and a couple others, came first) and I still get the occasional shakes thinking about tracking down bugs in complicated code. Then repunching the card or cards. (Who forgot to turn on the automatic serializer on the cardpunch, then dropped a deck? fun times)

    Ratfor was a hella improvement, in the sense that it reduced the hardcore spaghetti factor, but I still chose Pascal or Lisp when I could, for the easier debugging, if that says anything about how much I do not miss it..

  5. i am surprised that my disagreement isn’t a nitpick but rather the article’s repeated explicit main thrust!

    i do not think fortran is a DSL. it is YAPL.

    the thing about fortran is that it’s sseminal for so many things that we take for granted in every programming language today. it didn’t elide subroutine calls because scientists don’t need them. it lacked them because it was approximately the first “third generation programming language”! fortran wasn’t against function calls…rather the opposite. its most impressive result is showing that these problems are not only solvable but actually easy to solve. it inspired everyone that came after it to think of the incredible feats of mechanical language translation that are possible.

    Backus himself is quite explicit about it being Yet Another Programming Language in a 1978 retrospective on fortran. in as many words he says that the deign goal of the language was simply to have something that could justify the creation of a compiler. even in 1978, he knew he had to beg the audience to put themselves in the mindset of 1954 so that they could understand how incredibly primitive fortran’s innovations were https://dl.acm.org/doi/abs/10.1145/960118.808380

    and Backus himself became fond of functional style, once he had seen a couple decades of progress built on top of fortran’s core innovations. it’s clear that he views the 1950s as “trapped in the Von Neumann style” https://dl.acm.org/doi/10.1145/359576.359579

    fortran the language is just a footnote to the invention of the concept of a compiler for a high level language. the expression syntax wasn’t designed around the needs of scientists so much as it was designed around the theory that something new could exist in the world: an expression parser.

    anyways in real life fortran’s limitations are all pain for actual scientists. 25 years ago i had a summer job porting a large fortran nightmare from VMS to Linux using the awful Absoft fortran compiler. unfortunately i didn’t have access to actual users of the program so i found that 99.99% of the code was ‘unscientific’ and specifically unsuited to fortran. it was all UI and I/O. the actual math turned out to be just a histogram!!!! in real life, scientific programmers are often buried under mountains of poorly-factored code to implement very clunky UIs on top of I/O hardware that doesn’t exist anymore. and fortran was just about the worst language for all of the above.

    fortran itself belongs in the dustbin of history. it’s much worse for every problem domain than languages that came decades later. it is decidedly not like cobol or ada that are still valued within their domains.

    but the accomplishment that it represents is the foundation of everything that came after. it is the first yet another programming language.

    anyways i’m writing partly because i’m frustrated with the misrepresentations in the hackaday article. but i also hope some readers see the living history represented by these articles that Backus published which we can still read today. if anyone’s reading the articles i’m linking to, i hope they also glance at Guy Steele’s impassioned defense of function calls. if Bjarne Stroustrup had taken this seriously instead of delivering a meditation on the importance of inlining to mitigate the mythical expensive procedure call, we wouldn’t have to suffer C++ today. https://dl.acm.org/doi/10.1145/800179.810196

  6. Where are the FORMAT statements?

    I kinda learned FORTRAN after I already knew BASIC and it felt like a practical joke. With Basic on a microcomputer, like the Commodore PET at school or the Altair in my bedroom, you wrote and debugged a program interactively – and given my skills at the time, more time was spent debugging than writing.
    With Fortran, you wrote your program on paper, punched the cards and then mailed (US Postal service) the cards to the computer and they mailed the results back. I never got anything to actually compile and run.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.