Fortran essentials - introduction
Hello again! I haven’t had a lot of time to post recently, and the OpenMP series has correspondingly fallen by the wayside. I’ll still pick it back up at some point, but for now I wanted to switch focus to something that’s been taking up a lot of my energy at work: how to make Fortran not suck.
Why am I talking about Fortran?
For those not in the know, Fortran is a very old programming language dating from the 1950s, originally designed at IBM for numerical simulations. 1 A lot of people vaguely know about Fortran usually for one of two reasons:
- They had to learn it themselves (on punched cards if they’re an old-timer), or
- Because it’s become a memetic shorthand for bad programming practices.
There is a kernel of truth to this second point. The computing industry was still very much in its infancy when Fortran came on to the scene, so it predates the invention of a lot of modern (read: good) software engineering practices. It’s certainly possible to write good code in Fortran but the language features won’t help you do it the same way Rust or Julia does. It also has a bunch of weird idiosyncrasies if you’re used to languages which take their cues from C or ML, both of which post-date Fortran by decades. To be honest, Fortran would not be my first choice for a greenfield project, and really shouldn’t be used outside of numerical analysis.
Despite these well-known shortcomings, Fortran is still incredibly widely used throughout all fields of computational science … and that’s not necessarily a bad thing. On top of the usual arguments against rewriting legacy codebases2, Fortran also does a pretty good job within its niche. Its syntax pretty intuitively maps to mathematical formulae and it’s easy to write Fortran code which runs “fast-enough” without much programming experience; both of which make it useful for scientists looking to get results as quickly as possible.
The trouble arises when code which was meant to be a “quick prototype” (inevitably) becomes a critical component of somebody’s workflow and you suddenly find yourself needing to maintain it beyond its originally intended lifespan. This is an extremely common problem in all fields of software engineering, but, like I said above, Fortran itself won’t do anything to help you here. Fortran’s niche in high-performance computing means that a lot of development effort has gone into making it run fast, and comparatively little has been dedicated to things like development tools or language features improving maintainability 3. Up until recently, there haven’t been many high-quality, easily available Fortran resources, with most of the available knowledge spread between textbooks, blog posts and quasi-abandoned wikis. This made it hard to even figure out where to start when making improvements to your code.
It’s not hopeless, however! In a comeback story for the ages, the Fortran ecosystem has seen a big uptick over the last few years and there seems to be a lot more attention devoted to the problems I mentioned above. In particular, the fortran-lang project is extremely exciting to me. In their own words, they are “an open-source community that aims to develop modern Fortran tooling and nurture a rich ecosystem of libraries, as well as to provide a friendly, helpful, and inclusive space for newcomers and experienced Fortran programmers to work together”. Among other things, they’re working on a standard library, package manager modelled after Rust’s Cargo, and a centralised documentation hub; all of which should hopefully help to bring the Fortran ecosystem into the 21st century.
I’ve been mucking around with some of this stuff as part of my side-job and I figured it would be fun to document my learning process here. The next few posts will be an overview/review of various aspects of the ecosystem of modern Fortran and an explanation of how they make life easier for the Fortran programmer. My hope is to provide a resource that’s a companion to the standard textbooks and resources: a good Fortran textbook can teach you how to write code that works, this series will hopefully teach how to write software that’s stable and pleasant to use. Rather than just whinging about Fortran (which I could do indefinitely), this is my attempt to lead by example and demonstrate how I think things should be done.
This series will look at configuration file parsers, build systems, unit testing frameworks and anything other useful tools I come across in my day job. It’s intended for novice Fortran programmers to learn good practices from the get-go, but also experienced Fortran programmers who are proficient at writing numerical code, but maybe not so familiar with the software engineering side of things. And if you’re not interested in Fortran at all, I hope you’ve at least enjoyed this post enough to check out some of the others - you might learn a thing or two about a semi-obscure programming language. And who doesn’t want that?
Introductory resources
If you’re just starting out with Fortran or need a refresher, here are some basic resources I’ve found useful:
- fortran-lang.org: I’ve already mentioned this project, but they have some of the best beginner-focused documentation around. They also have a very comprehensive list of Fortran resources that you should definitely check out.
- The Fortran Wiki: Exactly what it says on the tin. It’s a bit terse in some places but overall very comprehensive and worth bookmarking.
- Fortran 2003 Handbook, Adams et al (2003): This is a good reference for new-ish features in Fortran but it is absolutely a reference manual, not a tutorial. Handy to keep around for when you need to look up some uncommon bit of syntax.
-
While researching this post, I found this neat oral history of the early days of Fortran by none other than John Backus, leader of the original FORTRAN team, and couldn’t resist sharing it here! ↩
-
In brief: rewriting mature software in a new language is extremely time-consuming, legacy code is often battle-tested and known to work (for certain definitions of “work”), and rewriting has a high probability of introducing subtle bugs. This is not to say that you should never rewrite a large codebase, since sometimes you accumulate so much technical debt that you have no choice but to do a partial or total rewrite. Like everything, there’s a complex set of tradeoffs at play; don’t go chasing the shiny new thing just because it’s shiny and new. ↩
-
I have sympathy for the Fortran committee here, since they’ve decided that backwards compatibility is a hard-constraint of each new standard. This is understandable, since Fortran’s main strength is its use in mature, well-tested scientific libraries (and who wants to deal with cranky emails from the DoE because you broke their nuclear weapons code?), but it does inherently limit their ability to make necessary changes to the structure of the language. ↩