Lessons Learned From Fortran

I last did FORTRAN in mmmm about 1996. If it's dead, it's only recently deceased. I was lucky enough to be using Fortran 77, though. Not too many GOTO's.

Things I learned from FORTRAN:

Things I learned about FORTRAN: Things I wished I had known: 90% of all of my bugs were mismatched COMMON blocks

In this system, programs shared data through named COMMON blocks that were located at the same place in memory. This FORTRAN compiler had the ability to read "include" files, just like C, so a COMMON block could be defined OnceAndOnlyOnce. However, there was no make. If you changed a common block, you either had to rebuild the whole system to be sure -- something that took so long you started it before you left for the night -- or just recompile the programs you think are affected. This lead to a lot of problems because I didn't compile a program that used the COMMON block I just modified.

Why didn't I write a make like tool to automate this? I wasn't smart enough:

I wish I had known to write more tools and MiniLanguage?s

There were some repetitive things that I should have done with custom tools and mini-languages. Although I knew the rule of "OnceAndOnlyOnce," I only applied it to code, not to my labor. Knowing what I know now, I should have written more scripts and mini-languages to automate the repetitive parts of my job.

For example, I spent many hours debugging mismatched COMMON blocks due to having not recompiled one of the programs that used the COMMON block that changed. If I had stopped to write a make type utility, it would have saved me a great deal of time and grief. The worst part of it was when I'd gratuitously recompile the whole system (a process taking hours) because a mismatched COMMON block might be the problem. I must have wasted person-weeks doing that.

Another example: Adding a new communication channel to the system meant editing half a dozen different source files -- add the comm channel definition to this ile, define the i/o device in that file, allocate COMMON blocks in another place, etc. I should have written a tool to automate all that. Not only would it have paid off for me, it would have let the customer change communication definitions without having to call me.

The lesson? OnceAndOnlyOnceIsNotJustForCode.

Why was the communication channel definition spread out in all those different files, and not in just one file? It was legacy code, and that's how the original programmers did it. But I could not change it because:

I wish I had known about automated UnitTests and FunctionalTests

The system was all legacy code. Some things were done really well, other things not quite as well. In that respect, it was no different than any other well-written legacy code. However, there were no unit or functional tests, and I didn't know to create them. Without tests, refactoring the code was an extremely dicey proposition. Most of my modifications were patch-like, changing as few lines as possible. Anything more than a patch usually meant rewriting the whole subroutine, or in a few cases, the whole module, because refactoring without tests is much more dangerous than rewriting.

Even today I'd be a bit afraid to retrofit tests onto this system. It was distributed, meaning that a great deal of code would have to be modified just to be testable. It would take a great deal of faith and courage to spend the time to write the tests.

Implementation restrictions on identifier length really stink

Nothing hurt as much as system restrictions on identifier length. This made it surprisingly hard to write self-documenting code. The language let me have long identifiers, but the linker was limited to something short like six or eight characters. It's difficult to keep track of things when your program identifiers are longer than your linker identifiers ("does this program identifier share the same linker identifier as that program identifier? Wait, let me count characters..."), so I chose to limit my program identifier length to the linker's limits. That hurt a lot.

If I had to chose between either long identifiers or OOP, it would be a hard choice. Most days I would have said, "The long identifiers, please."

Hence the mini-language you didn't write to convert long names into a 6 digit hash? :)


CategoryFortran


EditText of this page (last edited April 29, 2003) or FindPage with title or text search