16

The Education of a Computer (1952)

Grace Murray Hopper

Grace Murray Hopper (1906–1992) had a remarkable professional career, duly honored today both in the name of the national meeting of women computer scientists (the annual Grace Murray Hopper Conference) and in the name of a U.S. Naval warship (the USS Hopper, a guided missile destroyer). In 1934 she received a PhD in mathematics from Yale, and until the start of World War II was a mathematics professor at Vassar, where she had earned her undergraduate degree. Starting around 1940 she tried to join the Navy, but was rejected as too old. In 1943 she finally was accepted into the Naval Reserve in spite of being underweight at 120 pounds. She was assigned to Howard Aiken’s Computation Lab at Harvard, where she programmed the Mark I and its successor machine the Mark II. She famously taped into a log book a moth that had caused a relay to malfunction. Her ironic notation “First actual case of a bug being found,” acknowledges that she didn’t coin the term “bug,” which was already engineering jargon for a machine error. More importantly, she recognized, as Aiken did, that the future of computing would be as much in business data processing as in scientific calculation.

In 1949 Hopper joined the Eckert–Mauchly Computer Corporation, which was commercializing the design that had come out of the Moore School (see page 90). That company was bought by Remington Rand, Hopper’s affiliation as listed in this paper; the company’s machine was called the UNIVAC. (After further mergers and acquisitions the company became UNISYS.)

In the 1940s there were no higher level languages, no parsers, and hardly even a usable symbolic representation for machine code. There were no compilers and no debugging tools. The entire process of translating an algorithm into running code was done by hand, using paper and pencil until the very last step of inputting the program. Hopper here signals the beginning of the process of computers assisting programmers. The paper includes allusions not only to “compilers” (including what today would be called linking loaders and code relocation) but symbolic programming (she anticipates that computers will compute symbolic derivatives); code optimization trade-offs; global program analysis (“sweeping the computer information once to examine its structure”); macro-assembly language (referred to here as a “multiple-address code”); formal specifications of subroutines; hierarchical program structure; the redirection of attention from the kinds of numerical algorithms that had been so important during wartime toward commercial applications; and the recognition that the cost of software would in the long run vastly exceed the cost of hardware.

All these elements are in this paper, but they are not described straightforwardly. The paper is elaborately anthropomorphic. It is hard to tell at each stage of expansion and generalization where the line between human and machine is supposed to lie, because Hopper is anticipating that the line would shift over time—the computer’s “education” would advance. Within a couple of years she had become the head of “automatic programming” at Remington Rand, leading the development of the early programming languages ARITH-MATIC and MATH-MATIC (Ash et al., 1957), which seem to correspond roughly to the Type A and Type B routines of this paper.

Those languages were specific to the UNIVAC. But Hopper went on to be the determined force behind the development and standardization of COBOL (a COmmon Business Oriented Language), in the face of skepticism that computers could be made to handle data manipulations paraphrased in English-like vocabulary, and that the gains in programming efficiency from using such languages would far outweigh any loss in execution speed. She had a reputation as a stubborn, contrarian thinker throughout her life, using vivid metaphors to make her points. She brought “nanoseconds” to pass out in public talks in the form of foot-long segments of copper wire, and displayed a backwards-running clock with a mirror-image dial behind her desk to make the point that conventions are made to be broken.

Hopper had a distinguished career in the Navy, attaining the rank of Rear Admiral. I have a personal memory of her, one that suggests the obstacles that stood in the way of her career at every step. When she returned to Harvard in uniform in the 1970s, decades after her Mark I work there as a novice reservist, she was in a foul mood. The cabin crew of the airplane on which she had flown to Boston had treated the diminutive, gray-haired lady in the Navy admiral’s uniform with great deference—as a retired stewardess!


WHILE the materialization is new, the idea of mechanizing mathematical thinking is not new. Its lineage starts with the abacus and descends through Pascal, Leibniz, and Babbage. More immediately, the ideas here presented originate from Howard H. Aiken of Harvard University, John W. Mauchly of Eckert–Mauchly and M. V. Wilkes of the University of Cambridge. From Aiken came, in 1946, the idea of a library of routines described in the Mark I manual, and the concepts embodied in the Mark III coding machine, from Mauchly, the basic principles of the “short-order code” and suggestions, criticisms, and untiring patience in listening to these present attempts; from Wilkes, the greatest help of all, a book on the subject. For those of their ideas which are included herein, I most earnestly express my debt and my appreciation.

16.1    Introduction

To start at the beginning, Figure 16.1 represents the configuration of the elements required by an operation: input to the operations; controls, even if they be only start and stop; previously prepared tools supplied to the operation; and output of products, which may, in turn, become the input of another operation. This is the basic element of a production line; input of raw materials, controlled by human beings, possibly through instruments; supplied with machine tools; the operation produces an automobile, a rail, or a can of tomatoes.

Figure 16.1: An operation

The armed services, government, and industry are interested not only in creating new operations to produce new results, but also increasing the efficiency of old operations. A very old operation, Figure 16.2, is the solution of a mathematical problem. It fits the operational configuration: input of mathematical data; control by the mathematician; supplied with memory, formulas, tables, pencil, and paper; the brain carries on the arithmetic, and produces results.

Figure 16.2: Solution of problem

It is the current aim to replace, as far as possible, the human brain by an electronic digital computer. That such computers themselves fit this configuration may be seen in Figure 16.3. (With your permission, I shall use UNIVAC as synonymous with electronic digital computer; primarily because I think that way, but also because it is convenient.)

Figure 16.3: The UNIVAC system. [EDITOR: UNITYPER was a typewriter input device, UNISERVO a magnetic tape drive.]

Adding together the configurations of the human being and the electronic computer, Figure 16.4 shows the solution of a problem in two levels of operation. The arithmetical chore has been removed from the mathematician, who has become a programmer, and this duty assigned to the UNIVAC. The programmer has been supplied with a “code” into which he translates his instructions to the computer. The “standard knowledge” designed into the UNIVAC by its engineers, consists of its elementary arithmetic and logic.

Figure 16.4: Solution of a problem.

This situation remains static until the novelty of inventing programs wears off and degenerates into the dull labor of writing and checking programs. This duty now looms as an imposition on the human brain. Also, with the computer paid for, the cost of programming and the time consumed, comes to the notice of vice-presidents and project directors. Common sense dictates the insertion of a third level of operation, Figure 16.5.

Figure 16.5: Compiling routines and subroutines.

The programmer may return to being a mathematician. He is supplied with a catalogue of subroutines. No longer does he need to have available formulas or tables of elementary functions. He does not even need to know the particular instruction code used by the computer. He needs only to be able to use the catalogue to supply information to the computer about his problem. The UNIVAC, on the basis of the information supplied by the mathematician, under the control of a “compiling routine of type A,” using subroutines and its own instruction code, produces a program. This program, in turn directs the UNIVAC through the computation on the input data and the desired results are produced. A major reduction in time consumed and in sources of error has been made. If the library is well-stocked, programming has been reduced to a matter of hours, rather than weeks. The program is no longer subject either to errors of transcription or of untested routines.

Specifications for computer information, a catalogue, compiling routines, and subroutines will be given after adding another level to the block diagram. As Figure 16.5 stands the mathematician must still perform all mathematical operations, relegating to the UNIVAC programming and computational operations. However, the computer information delivered by the mathematician no longer deals with numerical quantities as such. It treats of variables and constants in symbolic form together with operations upon them. The insertion of a fourth level of operation is now possible, Figure 16.6. Suppose, for example, the mathematician wishes to evaluate a function and its first n derivatives. He sends the information defining the function itself to the UNIVAC. Under control of a “compiling routine of type B,” in this case a differentiator, using task routines, the UNIVAC delivers the information necessary to program the computation of the function and its derivatives. From the formula for the function, the UNIVAC derives the formulas of the successive derivatives. This information processed under a compiling routine of Type A yields a program to direct the computation.

Figure 16.6: Compiling Type B and task routines.

Expansion makes this procedure look, and seem, long and complicated. It is not. Reducing again to the two-component system, the mathematician and the computer, Figure 16.7 presents a more accurate picture of the computing system.

Figure 16.7: Computing system.

Presuming that code, program, input data, and results are familiar terms, it remains to define and specify the forms of information and routines acceptable to this system. These include catalogue; computer information; subroutine; compiling routines; type A and B; and task routines.

As soon as the purpose is stated to make use of subroutines, two methods arise. In one, the program refers to an immediately available subroutine, uses it, and continues computation. For a limited number of subroutines, this method is feasible and useful. Such a system has been developed under the nickname of the “short-order code” by members of the staff of the Computational Analysis Laboratory [EDITOR: at Eckert–Mauchly Computer Corporation].

The second method not only looks up the subroutine, but translates it, properly adjusted, into a program. Thus, the completed program may be run as a unit whenever desired, and may itself be placed in the library as a more advanced subroutine.

16.2    Catalogue and Computer Information

Each problem must be reduced to the level of the available subroutines. Suppose a simple problem, to compute y = ex2 sin cx, using elementary subroutines. Each step of the formula falls into the operational pattern, Figure 16.8; that is, u = x2; U = eu; v = cx; V = sin v; y = UV. As presented in Figure 16.9, however, this information is not yet sufficiently standardized to be acceptable to a compiling routine. Several problems must be considered and procedures defined. [EDITOR: Hopper here follows the footsteps of Lovelace—compare to Figure 3.1 on page 14.]

Figure 16.8: Operation

Figure 16.9: Example [EDITOR: aaL = “add to a limit” (Ash et al., 1957, page 86).]

The operations are numbered in normal sequence and this number becomes part of the computer information. Thus when it is desired to change the normal sequence, the alternate destination is readily identified. The compiling routine translates these operation numbers into instructions in the coded program. Two fundamental situations arise, the alternate destination either precedes the operation under consideration or follows it, by-passing several intermediate operations. In both cases, it is necessary only to have the compiling routine remember where it has placed each subroutine or that a transfer of control to operation k has been indicated. In any event the mathematician need only state, “go to operation k,” and the compiling routine does the rest.

The symbols to be used for the arguments and results, as well as for the operations, are of next concern. One mathematician might write y = ex2 sin cx, and another u = ev2 sin gv. The obvious solution proves best. Make a list of arguments and results and number them. (This amounts to writing all constants and variables as xi.) The order is immaterial, so that forgotten quantities can be added at the end (Figure 16.10).

Figure 16.10: Variable table for Figure 16.9

As symbols for the operations and subroutines, a system of “call-numbers” is used. These alphabetic characters represent the class of subroutines. Following Dr. Wilkes’ example, these symbols are partially phonetic; that is, a = arithmetic, t = trigonometric, and x = exponential; amc = arithmetic, multiplication by a constant; x-e = eU; ts0 = trigonometric, sine. Placed with the call-numbers, n, f, or s, indicates normal, floating, or stated (fixed) decimal point. Other letters and digits indicate radians or degrees for angles, complex numbers, etc. These call-numbers are listed in the catalogue together with the order in which arguments, controls, and results are to be stated.

16.3    Subroutines

Each subroutine in the library is expressed in coding relative to its entrance line considered as 001. They are, in general, programmed and coded for maximum accuracy and minimum computing time. They may store within themselves constants peculiar to themselves. They may also make use of certain “permanent constants” read in with every program. These permanent constants occupy a reserved section of the memory and are called for by alphabetic memory locations, a trick, at present peculiar to UNIVAC. Thus, these addresses are not modified in the course of positioning the subroutine in a program. They include such quantities as 1/2π, π/4, log10 e, ± 0,.2,.5, and the like.

Each subroutine is preceded by certain information, matching and supplementing that supplied by the mathematician:

1. call-number;

2. arguments, the destination of the arguments within the subroutine, expressed in the relative coding of the subroutines;

3. non-modification indicators locating constants embedded in the subroutine which are not to be altered;

4. results, the positions of the results within the subroutine, expressed in relative coding.

Each subroutine is arranged in a standard pattern.

Entrance line – The first line of a subroutine is its entrance line, thus in relative coding it is number one. It is the first line of the subroutine transferred to a program, and it contains an instruction transferring control to the first action line.

Exit lines – The second line of a subroutine is its normal exit line. This contains an instruction transferring control to the line following the last line of the subroutine. Unless an alternate transfer of control is desired, all exits from the subroutine are referred to the normal exit line. Alternate exit lines, involving transfers of control from the usual sequence follow the normal exit line in a predetermined order as listed in the catalogue.

Arguments – The exit lines are followed by spaces reserved for the arguments arranged in predetermined order.

Results – The results, also in specified order, follow the arguments.

Constants – The results are followed, when possible, by any arbitrary constants peculiar to the subroutine. When the subroutine has been compounded from other subroutines groups of constants may also appear embedded in the subroutine. These are cared for by the non-modification information.

The first action line appears next in the subroutine. Its position in the relative coding is defined by the entrance line. No instruction line may precede this line.

The sequence assigned to the entrance and exit lines, arguments, results, and constants is arbitrary. It is convenient. All that is required is that a sequence be established and that the computer recognize this sequence.

For convenience in manipulation, a certain number of elementary subroutines have been combined to form a sub-library. As subroutines are added to extend the library, it becomes more useful and programming time is further reduced.

Indeed, the day may come when the elementary subroutines are rarely used and the computer information will contain but seven or eight items calling into play powerful subroutines.

16.4    Construction of Subroutines

It is not necessary, nor is it advisable that the inexperienced programmer tamper with the coding within a subroutine. It is usually minimum latency coding using every trick and device known to the experienced programmer. It has been tested by operation on the computer.

Compiling Routines Type A are designed to select and arrange subroutines according to information supplied by the mathematician or by the computer. Basically, there is but one Type A routine. However since the UNIVAC code contains instructions transferring two neighboring quantities simultaneously, a second compiling routine has been designed to care for floating decimal, complex number, and double precision programs. For each operation listed by the mathematician a type A routine will perform the following services:

1. locate the subroutine indicated by the call-number;

2. from the computer and subroutine information combined with its record of the program fabricate and enter in the program the instructions transferring the arguments from working storage to the subroutines;

3. adjust the entrance and normal exit lines to the position of the subroutine in the program and enter them in the program;

4. according to the control information supplied by the programmer adjust alternate exit lines and enter them in the program (this process involves reference to the record);

5. according to the control information supplied with previous operations adjust auxiliary entrance lines and enter them in the program;

6. modify all addresses in the subroutine instructions and enter these instructions in the program;

7. according to information supplied by the subroutine, leave unaltered all constants embedded in the subroutine and transfer them to the program;

8. from the computer and the subroutine information fabricate and enter in the program the instructions transferring the results to [EDITOR: text missing, perhaps “working storage”].

9. maintain and produce a record of the program including the call-number of each subroutine and the position of its entrance line in the program.

The compiling routines also contain certain instructions concerning input tapes, tape library, and program tapes peculiar to the UNIVAC. All counting operations such as allocation of temporary storage and program space, and control of input and output are carried on steadily by the compiling routine. Stated bluntly the compiling routine is the programmer and performs all those services necessary to the production of a finished program.

Compiling Routines of Type B will for each operation, by means of “task routines,” replace or supplement the given computer information with new information. Thus, compiling routine B-1 will, for each operation, copy the information concerning that operation and call in the corresponding task routine. The task routine will generate the formula, and derive the information necessary to compute the derivative of the operation. Compiling routine B-1 then records this information in a form suitable for submission to a Type A routine.

Since information may be re-submitted to a type B routine, it is obvious that in order to obtain a program to compute f(x) and its first n derivatives only the information defining f(x) and the value of n need be given. The formulas for the derivatives of f(x) will be derived by repeated applications of B-1 and programmed by a type A routine.

It is here that the question can best be answered concerning a liking for or an aversion to subroutines. Since the use of subroutines in this fashion increases the abilities of the computer, the question becomes meaningless and transforms into a question of how to produce better subroutines faster. However, balancing the advantages and disadvantages of using subroutines, among the advantages are

1. relegation of mechanical jobs such as memory allocation, address modification, and transcription to the UNIVAC;

2. removal of error sources such as programming errors and transcription errors;

3. conservation of programming time;

4. ability to operate on operations;

5. duplication of effort is avoided, since each program in turn may become a subroutine.

Only two disadvantages are immediately evident. Because of standardization, a small amount of time is lost in performing duplicate data transfers which could be eliminated in a tailor-made routine. In base load problems, this could become serious. Even in this case however, it is worthwhile to have UNIVAC produce the original program and then eliminate such duplication before rerunning the problem. The second disadvantage should not long remain serious. It is the fact that, if a desired subroutine does not exist, it must be programmed and added to the library. This will be most likely to occur in the case of input and output editing routines until a large variety is accumulated. This situation also emphasizes the need for the greatest generality in the construction of subroutines.

Several directions of future developments in this field can be pointed out. More type A compiling routines will be devised: those handling commercial rather than mathematical programs; some special purpose compiling routines such as a routine which will compute approximate magnitudes as it proceeds and select sub-routines accordingly. Compiling routines must be informed of the average time required for each sub-routine so that they can supply estimates of running time with each program. For example, if both sin θ and cos θ are called for in a single routine, they will be computed more rapidly simultaneously. This will involve sweeping the computer information once to examine its structure.

Type B routines at present include linear operators. More type B routines must be designed. It can scarcely be denied that type C and D routines will be found to exist adding higher levels of operation. Work is already in progress to produce the formulas developed by type B routines in algebraic form in addition to producing their computational programs.

Thus by considering the professional programmer (not the mathematician), as an integral part of the computer, it is evident that the memory of the programmer and all information and data to which he can refer is available to the computer subject only to translation into suitable language. And it is further evident that the computer is fully capable of remembering and acting upon any instructions once presented to it by the programmer.

With some specialized knowledge of more advanced topics, UNIVAC at present has a well grounded mathematical education fully equivalent to that of a college sophomore, and it does not forget and does not make mistakes. It is hoped that its undergraduate course will be completed shortly and it will be accepted as a candidate for a graduate degree.

  1. Reprinted from Hopper (1952), with permission from the Association for Computing Machinery.