We ❤️ Open Source

A community education resource

6 min read

A Linux and Unix experiment – Part 1: Writing a FORTRAN 66 program

Here's what writing a FORTRAN 66 program was like using Unix from fifty years ago.

This article is a part of a series called “A throwback experiment with Linux and Unix.” Read the Introduction and set-up to the series.

For my “throwback” experiment, I wanted to demonstrate that you can still do real work on Linux, using just a terminal and the command line, just like the original Unix.

As a proof of concept, I worked for a week in Linux like it was Unix from fifty years ago. During this experiment, I assigned myself three tasks. The first task was to write a FORTRAN 66 program. This is my experience.

For reference, I’ve included a list of all user commands in Unix 4th edition.


Unix 4th edition commands reference guide


Write a FORTRAN 66 program

I learned FORTRAN 77 when I was an undergraduate physics student, so I associate “FORTRAN” with scientific computing. I wrote a FORTRAN program to iterate the physics equation of motion, of dropping an object from a certain height. Enter the height and the time step increment, and the program prints out the height of that object at each increment.

But my experiment was working in Linux like it was Unix 4th Edition, which means the then-current version of FORTRAN was FORTRAN 66. In that version of the language, FORTRAN 66 had added several programming constructs that were quite nice, such as DO loops and GOTO statements.

And while FORTRAN supported an IF statement, the language wouldn’t support IF .. ELSEIF .. ELSE .. ENDIF blocks until FORTRAN 77. To do the equivalent in FORTRAN 66, I had to write my IF blocks the old fashioned way.

If you don’t know FORTRAN, let me show you what this means using a kind of pseudocode. Let’s test if a number is greater than zero. Using a more modern programming language, you might write the test this way, in pseudocode:

 print 'enter starting height:'

 do {
   read height;
 } until (height > 0);

But old-style FORTRAN doesn’t have a loop like that; instead, you had to do it with IF tests and GOTO statements. With IF, FORTRAN could jump to lines that were labeled with a number. So to write a test to make sure a number is greater than zero, you might write pseudocode like this:

10   print 'enter starting height:'
     read height
     if (height less than or equal to zero) then {
       print 'must be greater than zero'
       goto 10
     }

But that uses an if-else style block. To write this without using an if-else block, you’d have to test for the opposite and jump around a bit, like this pseudocode:

10   print 'enter starting height:'
     read height
     if (height greater than zero) then goto 20
     print 'must be greater than zero'
     goto 10
20   .. rest of the program ..

And that’s why you may notice this FORTRAN 66 program uses IF and GOTO every time it needs to read a value from the user.

Because I was pretending to use Unix 4th Edition, I wrote the program using ed, not a visual editor like Emacs or Vim or Visual Studio Code. To edit a file using ed, you start by launching the editor with the name of the file to work on:

$ ed drop.f

With ed, you don’t get a prompt, so it may appear that that program isn’t doing anything – but really, it’s just waiting for you to type a command. Like Vim, the ed editor operates in one of two modes: command mode or edit mode. You start in command mode; to start entering lines, you need to give the i (insert) command. You can then enter new lines of text; enter . on a line by itself to stop:

i
C     A PROGRAM TO SIMULATE DROPPING AN OBJECT
     PROGRAM DROP
     DOUBLEPRECISION Y0,Y,T
10   WRITE(*,*)'ENTER STARTING Y:'
     READ(*,*)Y
     IF (Y.GT.0.0) GOTO 20
     WRITE(*,*)'** Y0 MUST BE GREATER THAN ZERO'
     GOTO 10
.

As I was typing that, I realized that I meant to use Y0 instead of Y on the READ and IF lines. I fixed it for the WRITE line, but I needed to go back and fix it on the previous lines before I forgot about it. To search backwards, use the ? command with the text to search for. In my case, let’s search backwards for the READ line:

?READ 
     READ(*,*)Y

I just need to change Y to Y0, so I can use the s (swap text) command for that. The search set the active line to the READ line, so I can use s to swap text on the active line like this:

s/Y/Y0/

To print the new line, use the p (print) command:

p
     READ(*,*)Y0

That worked! Now we just need to do the same for the IF line, on the next line. This time, we can search forwards with the / command:

/IF
     IF (Y.GT.0.0) GOTO 20
s/Y/Y0/
p
     IF (Y0.GT.0.0) GOTO 20

Having made those fixes, I’m ready to write the rest of the program. To jump to a specific line in the file, type its number. For example, to jump to to first line of the file and have ed print it, you would type 1:

1
C     A PROGRAM TO SIMULATE DROPPING AN OBJECT

To skip to the bottom of the file, type $:

$
     GOTO 10

With ed, you have to keep a mental “map” of the file you’re working on, tracking the approximate location in a file where a procedure might be defined. With some practice, this becomes natural. But because you can only work one line at a time, I find it’s much easier to sketch out an outline of the program on a piece of paper, and use that to guide me through writing the program.

From there, I was able to use ed to finish editing the program. To save and exit the ed editor, use the w command to write the file to disk, then q to quit.

C     A PROGRAM TO SIMULATE DROPPING AN OBJECT
     PROGRAM DROP
     DOUBLEPRECISION Y0,Y,T
     DOUBLEPRECISION INC
     T=0.0
10   WRITE(*,*)'ENTER STARTING Y:'
     READ(*,*)Y0
     IF (Y0.GT.0.0) GOTO 20
     WRITE(*,*)'** Y0 MUST BE GREATER THAN ZERO'
     GOTO 10
20   WRITE(*,*)'ENTER TIME INCREMENT:'
     READ(*,*)INC
     IF (INC.GT.0.0001) GOTO 30
     WRITE(*,*)'** TIME INCREMENT IS TOO SMALL'
     GOTO 20
30   Y=Y0 - (0.5 * 9.8 * T*T)
     WRITE(*,*)T,Y
     T=T+INC
     IF (Y.GT.0.0) GOTO 30
     WRITE(*,*)'DONE'
     END

Now I’m ready to compile my program with the fc FORTRAN compiler! Note that fc didn’t use -o to set the output file name; it always saved to a.out. To get the final program as drop, you need to rename it:

$ fc drop.f
$ mv a.out drop

And now we know that dropping an object from 1 meter will take less than half a second to reach the ground:

$ ./drop
ENTER STARTING Y:
0
** Y0 MUST BE GREATER THAN ZERO
ENTER STARTING Y:
1
ENTER TIME INCREMENT:
0
** TIME INCREMENT IS TOO SMALL
ENTER TIME INCREMENT:
.1
  0.0000000000000000        1.0000000000000000     
 0.10000000000000001       0.95099999904632571     
 0.20000000000000001       0.80399999618530271     
 0.30000000000000004       0.55899999141693102     
 0.40000000000000002       0.21599998474121085     
 0.50000000000000000      -0.22500002384185791     
DONE

More from We Love Open Source

About the Author

Jim Hall is an open source software advocate and developer, best known for usability testing in GNOME and as the founder + project coordinator of FreeDOS. At work, Jim is CEO of Hallmentum, an IT executive consulting company that provides hands-on IT Leadership training, workshops, and coaching.

Read Jim's Full Bio

The opinions expressed on this website are those of each author, not of the author's employer or All Things Open/We Love Open Source.

Register for All Things Open 2024

Join thousands of open source friends October 27-29 in downtown Raleigh for ATO 2024!

Upcoming Events

We do more than just All Things Open and Open Source 101. See all upcoming events here.

Open Source Meetups

We host some of the most active open source meetups in the U.S. Get more info and RSVP to an upcoming event.