C:\ANCIENT\FORTRAN.TXT
1957
FORTRAN: The Formula Was the Starting Point
FORTRAN's IBM 704 compiler brought formula-based source and attention to efficient generated code together, changing how numerical programs could be prepared.
An engineer has five measurements and wants their average. The mathematics fits on a small piece of paper: add the readings, then divide by five.
Preparing a machine program adds other work. Values need locations. Repetition needs control. Arithmetic needs an instruction sequence, and that sequence should make reasonable use of an expensive computer.
Formula translation shifts some of those decisions into software. The author writes numerical relationships in a source language; a compiler constructs the machine instructions that will carry them out.
FORTRAN made that arrangement useful for numerical work while taking the efficiency of the generated program seriously. Easier preparation was valuable. An easier way to write a very slow program would have been a less persuasive sales pitch.
A manual before delivery
John Backus led the IBM team that developed FORTRAN, with its commercial debut in 1957 for the IBM 704. The work was collaborative: contributors included David Sayre, Harlan Herrick, Roy Nutt, Peter Sheridan, Lois Haibt and others.1
The reference manual inspected here is dated October 15, 1956. It describes a source language and a compiler producing 704 machine-language object programs; its advance availability language doesn’t establish that the finished compiler had shipped then.2
Its numerical syntax and control forms provide the period anchor. The original examples below explain the distinction between a compact source description and the larger work needed to execute it. They’re not evidence that a modern Fortran compiler reproduces the original compiler’s choices.
The capitals in FORTRAN belong to this early system. The decades of later language development aren’t being packed into the launch release.
A short source can describe repeated work
Use an invented set of readings: 3, 7, 2, 9 and 4. Their sum is 25 and their mean is 5.
A small period-style fragment, assuming the five values are already loaded into A, can describe the summation:
DIMENSION A(5)
S = 0.
DO 20 I = 1,5
20 S = S + A(I)
AV = S/5.
The original manual’s conventions make I a fixed-point integer index and S and AV floating-point variables. The labeled statement 20 ends this positive, inclusive loop. The fragment omits input/output and the rest of a complete run; it is original illustrative source, not a recovered example.2
The syntax saves the author from spelling out five separate additions. It also makes the intended relationship visible: S receives its old value plus the selected array element.
An assignment is an action, rather than a timeless algebraic equality. S = S + A(I) would be an odd mathematical equation if both appearances of S meant one unchanged quantity. In a program, the right side uses the prior S and the left side receives the replacement.
That distinction is where the running total lives.
| Readings processed | Latest reading | New total |
|---|---|---|
| 1 | 3 | 3 |
| 2 | 7 | 10 |
| 3 | 2 | 12 |
| 4 | 9 | 21 |
| 5 | 4 | 25 |
After each step, the total represents exactly the readings processed so far. This is an invariant: a relationship that should remain true as execution progresses.
If the routine starts with S = 100 instead of zero, it finishes with 125. Every subsequent addition can be individually correct while the overall result is wrong. Initialization is part of the algorithm, even when its source statement looks less impressive than the formula that follows.
Original explanatory SVG, created in 2026. Readings and arithmetic belong to the article’s teaching example, checked in modern Python rather than an IBM 704 environment.
Translation has to supply a route
A compiler can’t hand the processor the phrase “do this five times” and expect the phrase to execute by courtesy. It must produce operations that manage the repeated calculation under the target machine’s rules.
Conceptually, a straightforward route has to select an element, obtain the old sum, add, preserve the replacement, advance the position and decide whether to repeat. This is a general explanation of compilation, not a purported disassembly of the 1957 compiler’s output.
The source is shorter because it names useful relationships at another level. The compiler is responsible for realizing that level as instructions. Compact notation relocates complexity; it doesn’t dissolve it.
The count also participates in the mathematics. Divide the correct sum by six and the result is about 4.1667. Omit the final reading while retaining a divisor of five and the mean becomes 4.2. A compiler can implement both requests faithfully. Choosing the matching count and input range remains the programmer’s job.
This separation explains why a translated program can be well-formed and wrong. Syntax checks concern the description’s legality. Data selection, units and intended relationships require additional evidence.
One product used twice
Another original example exposes why translation quality matters. Consider the expression:
R = (U*V) + (U*V)
For U = 3 and V = 4, each product is 12 and R is 24.
A literal evaluation can multiply twice and then add. Another route computes the product once, saves it as P and uses it for both sides of the addition:
P = U*V
R = P + P
The invented operation count falls from two multiplications to one. That is a count of this teaching expression’s work, not a measured compiler speedup or machine-cycle total. Keeping a temporary result may have costs too; the best route depends on what the machine can retain and what other work is happening.
Original explanatory SVG, created in 2026. The invented dependency model illustrates a translation choice, rather than claiming an exact original compiler plan.
A common subexpression is a repeated part of a calculation that can be computed once when its inputs and meaning remain unchanged. Recognizing one requires more than spotting identical text.
Suppose U changes between two separate product evaluations. Reusing the earlier P would give the second use an old input. The text still says U times V, but the computations no longer refer to the same state.
Even within an expression, functions or machine rules can make seemingly obvious transformations unsafe. A compiler needs a definition of what it is allowed to preserve and change. Optimization is a claim of equivalence under those rules.
The early manual explicitly discusses efficient arithmetic translation and warns that some repeated-subexpression recognition depends on suitable parentheses.2 The original compiler wasn’t an all-seeing algebraic editor. How an expression was written could affect the work it recognized.
Finite arithmetic has opinions
Ordinary algebra offers attractive rearrangements. Stored numerical arithmetic has limits: it retains a finite number of significant digits and must round results that don’t fit.
For a deliberately separate teaching model, use decimal arithmetic with three significant digits. This is not the IBM 704 format. It makes a rounding effect small enough to inspect.
Compare two groupings of the same three numbers:
and
In exact arithmetic, both are 1. In our three-digit model, 1000 plus 1 rounds to 1000, so the first grouping gives zero. In the second, 1 minus 1000 is −999, which fits exactly; adding 1000 gives 1.
The compiler cannot assume that every real-number identity is harmless in a finite representation. A rearrangement can change when information is discarded.
This isn’t an argument against optimization. It explains why the permitted transformations need a specified arithmetic contract, and why numerical programmers may care about grouping. Getting a faster zero isn’t an improvement when the required result is one.
The checker verifies this example with a modern decimal context at precision three. It separately tests our integer-valued measurement sum and repeated product. Those checks establish the defined teaching results without suggesting that Python emulates the 704’s floating-point representation.
What the source buys the reader
The summation fragment also helps somebody reviewing the calculation. Its array, range, running sum and divisor are visible together. The reviewer can ask whether there are five readings, whether every selected value belongs, and whether the units are compatible.
Those questions are harder to keep in view amid a long sequence of low-level transfers and branches. A source language supplies an organizing description that can be inspected before following the generated route instruction by instruction.
That doesn’t make the lower level irrelevant. If a program has surprising behavior or performance, its translation decisions can matter. The relationship between source and execution is an engineering responsibility, not a guarantee that the author will never need to investigate the machine again.
There is also a boundary around the example’s apparent simplicity. Input representation and output formatting have been omitted intentionally. A complete measurement program must obtain values and present results, handling errors and conventions appropriate to its environment. A neat arithmetic fragment is one part of that program.
Efficient code made the abstraction credible
I find FORTRAN’s combination of concise source and attention to generated work more persuasive than a story about replacing all specialist knowledge overnight.
The author gains a place to state numerical relationships. The compiler takes on translation decisions, including opportunities to share calculations and organize execution. The reviewer gains a shorter description against which to check the intended mathematics.
Our five readings still require correct initialization, range and division. Our repeated product still requires stable inputs. Our rounded example still requires a defined numerical interpretation.
Formula translation makes those responsibilities easier to express. Its success depends on a compiler that preserves them while constructing a workable route through the machine.
Footnotes
-
IBM, “Fortran”, read for Backus’s team, contributor names, IBM 704 target and 1957 debut. Its broad promotional firsts and universal performance claims are not adopted here. ↩
-
IBM, The FORTRAN Automatic Coding System for the IBM 704 EDPM: Programmer’s Reference Manual, October 15, 1956. PDF pages 8–12 and 21–23 support the source fragment; pages 41–42 discuss arithmetic optimization and parentheses. This advance manual is distinct from 1957 delivery. The examples and decimal model are original, and their modern checks do not reproduce the original compiler. ↩ ↩2 ↩3