Book report, part 3: Introduction to Programming with Fortran
I've definitely been putting off this review since I've been focusing more lately on projects to put all this reading to use. In fact, if you haven't already, you can check out the new FEM code modernization and Fortran unums projects. But, I don't want to get into a habit of not finishing things, so without further ado, my review of the third and final installment of Introduction to Programming with Fortran.
So to start with, some positive things. The very broad net that the authors cast in the first two reviews continues here. Generally speaking, the most important topics from my point of view are the (newer) object oriented functionality, parallel processing (OpenMP, MPI, and coarrays), and C interoperation. Combined, these features are a large part of what makes Fortran such a powerful language for high performance computing (HPC, or I believe it's safe to generalize as just "supercomputers"). It's also been more proof to me that Fortran is not some archaic language to be rooted out and replaced with something more modern, whatever that means. Sure, pre-modern Fortran is kind of a mess, and lacks many key features that not only are to be expected of a modern programming language, but it also lacks many features that make modern Fortran so compelling. Sadly, it seems most people are familiar with pre-modern. One of my friends learned Fortran in college in the mid-90s, and even though modern Fortran should have been available, they were taught Fortran 77.
Object-oriented functionality is definitely common in modern programming, and so modern Fortran has incorporated it as well. Largely, it fits into the language through types, similar to structures in a language like Matlab, except with the ability to add in functions and control access. The book has decent examples of inheritance and overloading, but I found the examples to be overly simplistic. This is a bit of a common criticism I have with the examples, that they do illustrate a particular feature or function, but you're often left with the question as to when you would use it or why to use it over other implementations. I have no doubt I'll use this chapter as a reference, but if I weren't already familiar with object-oriented ideas, I might struggle to understand why I would need it in the future.
Fortran certainly isn't unique in parallelizing tasks. I've done it in Matlab, and experimented with some basic examples in Julia, but Fortran offers a number of options depending on the nature of the calculations you're trying to perform. If you're interested in what makes Fortran the language of HPC, whether you agree or not, I would recommend this talk given by Damian Rouson and Alessandro Fanfarillo of the Sourcery Institute at the 2017 HPC Advisory Council Stanford Conference.
However, this is a review of Introduction to Programming with Fortran, so how did this book hold up in introducing these topics? Adequately I would say. I'm torn because I spent an inordinate amount of time figuring out now to run the code examples given because they need either special compiler options or additional software installed. The book does give links to follow to learn more about how to get OpenMP or MPI working, but does little after that. Like it did from the beginning in not walking through what a compiler is or how to use one, the exercise is left to the reader to actually figure out how to run anything. This is very frustrating, although at the same time I understand replicating website instructions is treacherous as they can change at any time. Still, I would have liked more guidance than what I was given, and it would have made my life a bit easier.
Also, the book gives pretty much the same code example (a way to parallelize the calculation of pi) for all parallelization types. The continuity can help to compare the syntax for each type, but it can be very repetitive (because, well, it is) and the comparative advantages and disadvantages of each type aren't made obvious. My understanding is that there are important differences, as types can vary on how they allocate system resources and so certain tasks are better suited for different parallelization types.
Fortunately, the C-interop was much simpler on a "getting it running" level. I've been using the GNU toolset, which has both a C compiler (gcc) and a Fortran compiler (gfortran) and so many of the compiler options I was used to running on one worked on the other. Like my previous criticisms of especially these more advanced feature code examples, I found the book's examples pretty simple, and the description of why this is a useful feature to be pretty terse. Which is a shame, because in addition to working more easily with other C code, it also makes Fortran code much easier to call from anything that can interface with C. So, for instance, Julia I think largely uses the C interface to work with Fortran code. And, of course, the more places where this can happen, the more broadly useful anything written in Fortran becomes.
The remaining chapters and topics felt really slapped on. The chapter on IEEE arithmetic was interesting, but oddly placed considering that one of the first chapters in the book had a lengthy discussion on numerical precision. Another chapter is simply entitled "Miscellaneous Examples," further giving the impression that the farther one gets into the book, the more the topics were added simply for completeness and not necessarily well incorporated into the overall flow. In this chapter I was mainly interested in the graphic and plotting library (dislin), but couldn't get it working without, if the internet is to be believed, disabling "System Integrity Protection" on my laptop, so I passed. I did notice other places where the book simply referred to the website to see the example code, which frankly came off as lazy given the many, many pages in this book devoted to source code. Maybe these particular examples were just too verbose to fit, but they were noted as similar to another, included example, so I don't believe they would have been.
Finally, there was a chapter on how to convert Fortran 77 to modern Fortran. There's a list of deprecated features and what to replace them with, but virtually no explanation. For instance, I'm to replace H editing with character edit descriptors. I have no idea what H editing is, and for, again, a book that's an "introduction" I feel it's a big omission to not explain these topics in a way someone new to Fortran or programming in general can understand. There is a list of commercially available software for automatically converting pre-modern Fortran to modern, as well as a short code example given with how it would have changed over various standards. It's useful, however given how much legacy Fortran code is out there in the world, I feel like this could have done with a lot more explanation. For instance, now that I've looked through some legacy Fortran, I've seen a lot of usage of common blocks. So far as I can tell, the only guidance in the book is to replace them with modules, but nothing else on how they work. Also, again now that I have experience, a table for how to figure out inferred types would be helpful. In general, I can't help but feel that the only reason for this chapter to exist is to be able to claim coverage of Fortran 77 on the cover.
So that's it, all ~600 pages of Introduction to Programming with Fortran. In spite of my many complaints with this book, I have learned a lot by going through it. I'm sure I will go back and consult certain chapters as reference, although I have to admit it is sometimes difficult to use as a a reference due to the book's organization. As much as I'm glad I went through the exercise, I can't help but feel that there's a better book in there somewhere. If you're considering buying it, I would recommend you be more in need of an introduction to Fortran than an introduction to programming. And while I still need to finish reading it, I suggest you pair it with something like Modern Fortran: Style and Usage by Clerman and Spector to really understand the why of certain programming choices and to learn to write clear, comprehensible, stable code.