THE LINCOLN RECKONER: AN OPERATION-ORIENTED,
ON-LINE FACILITY WITH DISTRIBUTED CONTROL
Arthur N. Stowe, Raymond A. Wiesen, Douwe B.
Yntema, and James W. Forgie
Lincoln Laboratory, * Massachusetts Institute of
Technology
Lexington, Massachusetts
tine, all the user has to do is type the name of the
routine, the name or names of the operands on
which he wants it to operate, and the name or
names under which he wants the results to be filed
away for future reference.
Suppose for example that two arrays, X and Y,
have already been loaded into the system: X is an
m X n array and Y is m X 1. The user would like to
find the coefficients /3 j that minimize the expression
GENERAL DESCRIPTION
OF THE RECKONER
The Lincoln Reckoner is a time-shared system for
on-line use in scientific and engineering research. It
looks forward to the day when a computational
service can be put into the office of every serious
research worker, and it was designed as an experiment to find out what features of such a service will
have an important effect on the amount of work the
user gets done.
The present system does not by any means offer
all of the services that a computer might provide to
scientists and engineers. Instead, it offers a library of
routines that concentrate on one particular application, numerical computations on arrays of data. It is
intended for use in feeling one's way through the
reduction of data from a· laboratory experiment, or
in trying out theoretical computations· of moderate
size.
~ (Yi- ~ Xij.{3j) 2
i
Let us assume he knows some matrix algebra: he
realizes that the desired coefficients are the components of the column-vector ,{3 that may be found by
solving the matrix equation
X' X X X f3 == X' X Y
in which X and Yare the given arrays and X' is the
transpose of X. To find {3 he might then type the
four lines shown in Example 1.
Using Routines from the Public Library
Example 1:
TRANSPOSE X XPRIME
MATMUL XPRIME X L
MATMUL XPRIME Y R
SOLVELRBETA
The Reckoner is primarily a facility for making
use of routines, not for writing them. To run a rou-
* Operated
j
with support from the U.S. Air Force.
433
From the collection of the Computer History Museum (www.computerhistory.org)
434
PROCEEDINGS-FALL JOINT COMPUTER CONFERENCE, 1966
The first line says that the array named X is to be
transposed and the resulting array is to be called
XPRIME. TRANSPOSE is the name of the routine
that transposes a matrix (i.e., a two-dimensional array), X is the name of the array on which the routine is to operate, and XPRIME is the name under
which the user wants the result to be filed away.
When he has typed this line and has pressed the
carriage-return key on his typewriter, the system
performs the operation without further ado. He need
not know where TRANSPOSE and X are stored,
and he need not concern himself with the dimensions of the operand X or of the result XPRIME.
The second line says that the matrix XPRIME is
to be post-multiplied by the matrix X and the product is to be called L. MATMUL is the name of the
matrix-multiplication routine, there are two operands, named XPRIME and X, and L is the name
the user wants to give to the result.
The third line is similar, and the fourth says that
the matrix equation
LXf3=R
is to be solved for ,/3. Land R are the names of the
operands, SOLVE is the name of the routine, and
BETA is the name for the result.
At this point the user may want to see how well
each of the approximations 2.j Xij .f3j agrees with the
corresponding Yi. He might therefore type
MATMUL X BETA XBETA
PLOTXBETA Y
The first line multiplies the m X n matrix X by the
n X 1 matrix BETA to produce the m X 1 matrix
XBETA, and the second produces on a cathode-ray
tube near the user's typewriter a graph of the elements of XBETA plotted against the corresponding
elements of Y. The routine chooses the scales for
the two axes, puts tick marks on the scales at intervals chosen to conform to custom and readability,
and decides whether to ·label every tick mark or
every fifth one. There are other routines, with additional parameters, that allow the user to specify the
ranges of one or both of the axes.
Building and Using a «Process"
As the user works on a· problem, he often finds
himself using over and over a series of operations
that he has come to regard as a single unit. When he
does, he will probably want to define a "process"
that will allow him to run off the whole sequence
with a single statement. For example, he may come
to think of the four lines shown in Example 1 as one
unit, a least-squares fit. To make the four lines into
a process he could proceed as shown in Example 2.
Example 2:
BUILDLSF
GOON
TRANSPOSE X XPRIME
MATMUL XPRIME X L
MATMUL XPRIME Y R
SOLVELRBETA
/ FINIS
OK
On the first line, BUILD is the name of the routine
that constructs a new process, and LSF (for "leastsquares fit") is the name the user wants to give the
process. The system responds GO ON to show it is
ready to accept the definition of a process, and he
types the four lines that constitute the definition.
Then he types /FINIS to show he is through, and
the system responds OK. Henceforth, whenever he
types LSF followed by a carriage return, the system
will perform the four statements exactly as though a
rapid typist had typed them very quickly. Processes
can call upon processes: the statement LSF can appear in the definition of another process, which can
be called by yet another process, and so on.
Sometimes it is convenient to let a process have
operands and results so that it can be used like one
of the primitive routines in the library. If the user
had chosen to make LSF a process of this kind, he
could have proceeded as in Example 3.
Example 3:
BUILDLSF
GOON
pABC
TRANSPOSE A .APRIME
MATMUL .APRIME A .L
MATMUL .APRIME B .R
SOLVE .L .R C
/FINIS
OK
The line beginning with the circled p is the parameter line: it shows which of the names that appear in the process are to be treated as variables
that the user will specify when he asks for the proc-
From the collection of the Computer History Museum (www.computerhistory.org)
LINCOLN RECKONER: AN OPERATION-ORIENTED, ON-LINE FACILITY
ess to be performed. For example, if he types the
line
LSF X Y BETA
the process will be run off just as though the four
statements were typed by a rapid typist who was
instructed to substitute X where A appears,'y wherever B appears, and BETA where C appears.
The curious names that begin with periods are
names for intermediate results that the user does not
want preserved after the execution of the process is
complete. The system automatically adds to each of
these names a prefix composed of a period and the
name of the process itself. For example, wherever
the user has written .R, the fictitious typist· writes
.LSF .R, so that .R becomes in effect a local name
peculiar to this·process; thus if the statement
LSF X Y BETA
appears in another process in which the name .R is
used, the two results called .R will not be confused.
When the execution of the process is complete, the
system automatically makes the name .LSF .R
undefined so that it will not clutter up the user's
records.
The versatility of processes is greatly increased by
two features that have not been illustrated by these
examples. First, processes may include unconditional and conditional jumps. For example, when the
line
__ 5.5
appears in a process, it means "jump to Line 5.5 of
this process"; and the line
. . - 5.5 ALPHA > Z
means "jump to Line 5.5 of this process if the current value of the scalar named ALPHA is greater
than the current value of the scalar named Z." (The
lines of a process all have numbers, though the user
need not bother to type them if he wants the lines
numbered simply 1, 2, 3, . . . ) Second, there is a
symbol, <I), which means "now exit from this process." This symbol did not appear in the examples
because a process is always understood to have an
exit at the end.
Since the user is able to construct processes that
contain conditional jumps and behave like library
routines, the public library of basic routines does
not have to be very large. The present library, which
is specialized for numerical calculations on arrays of
real numbers, is described in the Appendix. It contains only 64 operations-some large, many trivial.
While it is easy to think of other operations that
435
might well be included, we have been pleased and
a little surprised to find how adequate this small
library is.
Further Details
The Reckoner has some other features that
should be mentioned because they greatly affect the
appearance of the system to the user. It is easiest
just to list them:
1. There is a buffer area in which the system
stacks inputs from the user's keyboard. After typing
a carriage return, which is the signal to execute a
statement, he may begin a new statement immediately without waiting for an indication that the
system has finished executing the old one~ Stacking
inputs in this fashion is a cheap way to increase the
apparent speed with which the system responds: the
system can be working on one statement while the
user is typing the next. Indeed he never needs to
wait for the system except when he types a command
that calls for an output, and when he goes into or
out of the process-builder. (In theory he would have
to wait if he typed fast enough to fill the buffer,
which is set to hold about 700 characters; but no
one has ever filled it so far as we know.) There is of
course an unpleasant moment of confusion if he is
typing a statement when the system begins to type
an error-message about some previous statement,
but the occasional unpleasantness is. a small price to
pay for the apparent increase in speed of response.
2. The user may edit the definition of a process:
he may make changes before he has typed the
[FINIS that shows the definition is complete, and he
may reopen the process later, perhaps after he has
tried it, and make changes then. Lines are replaced
and deleted by number, and are inserted by giving
them intermediate lirie-numbers. Line-numbers
may have up to four decimal digits before and four
after the decimal point.
3. A name may be 50 characters long, and may
consist of any combination of digits, periods, and
roman capital letters, provided it contains at least
one letter. However, it'is unwise to choose a name
beginning with a period or a digit; names that begin
with periods can be confused with names of intermediate results, and names that begin with digits
are sometimes used by the system for its own purposes.
4. There is an operation (i.e., a public routine)
by which the user may specify that one name shall
From the collection of the Computer History Museum (www.computerhistory.org)
436
PROCEEDINGS-FALL JOINT COMPUTER CONFERENCE, 1966
have the same meaning as another. For example, the
basic public name of the matrix-multiplication routine is 5MMUL. If the user does not like that name
-and presumably he will not-he may create a
synonym like MA TMUL, the name used in the examples. He may also create synonyms for the names
of his own processes and arrays of data. In particular, he may create one- or two-letter synonyms for
names he uses often.
terpretively, as will be explained below. (4) Intermediate results of the sort illustrated in Example
3 are handled in such a way that a process can be
recursive: if the process is called PROC, and it is
already in use on another level, then the prefix added to names of intermediate results is .1 .PROC instead of .PROC; if it is already in use on two levels,
then the prefix is .2 .PROC; and so forth.
5. When a name is given a lfew meaning-either
by making it a synonym to another name, or by
using it as the name for the result of an operationit is detached from its old meaning, if any, and attached to the new meaning; if it did not have synonyms, the thing to which it referred is forgotten. The
system does all this without any comment or warning. This arrangement appears to be proper and
convenient from the user's point of view; but it does
imply that when he wants to protect a valuable file
of data, he should give it a long, complicated name
that he is not likely to reuse inadvertently.
Three Case Histories
6. A process may be interrupted by the interrupt
button, by a special statement in the process itself,
or by an error message. The process is put into a
suspended state-and so is the process, if any, that
called for it, and the process which called for that
one, and so on. Control is returned to the keyboard,
and the user may print the results obtained so far,
plot them, or do subsidiary calculations on them. In
doing so he uses library routines and existing processes just as he usually would; he is even free to
define and use new processes. He uses names like
.LSF.R, which was discussed in connection with Example 3, when he wants to refer to intermediate results of a process that is in suspension. If he wishes
he may tell the system to continue the complex of
suspended processes, starting where it left off.
There are several other details of more interest to
the professional programmer than to the typical
user: ( 1) The routines in the present library do all
calculations in single-precision, floating-point arithmetic (9-bit exponent; 27-bit fraction, including
sign) and simply take the nearest integer when an
integer is needed-e.g., for the number of rows in
an array. (2) At present all arrays are n-dimensional rectangular arrays of single-precision, floatingpoint numbers; the number of elements in an array
may not exceed 8190n. (3) The routines in the
public library are binary, reentrant, closed subroutines that occupy fixed addresses; processes run in-
Our general impression is that the Reckoner is a
good, workaday facility for doing calculations with a
minimum of fuss about clerical details. We have
chosen three case histories to illustrate how the system works out in practice. The Reckoner is sometimes used to attack sizable problems that require
many hours of work, but for the sake of brevity, we
have chosen short cases.
Case A. Senior member of the Laboratory's staff;
poor touch-typist; had written programs as pencil
and paper exercises but never run them; using the
Reckoner for the first time, spending an hour trying
it out with the help of an experienced user.
Spent about 10 minutes typing small arrays into
the system and doing various operations on them
more or less at random. Then turned to a problem
that had arisen the previous day in his work: Iteratively compute the vector S from the equation
C X Sp
+V
-----=Sn
6
where C is a square matrix, V is a column-vector
with each element equal to 2, Sp is the value of S
from the previous iteration, and Sn is the new value.
Typed a 5 X 5 matrix C and an initial vector S into
the system, and with occasional coaching from the
experienced user, did one round of the iteration and
typed out the elements of S. Applied the process
repeatedly until S stabilized.
Did not believe the results, and spent about five
minutes with pencil and paper thinking about the
physics of the problem. Tried another initial value
of S, got the same results, and then saw they were
reasonable. Asked if he wanted to save his files,
said, "No, I have my answer."
Time: 55 minutes, including some discussion of
the purpose of the Reckoner.
Case B. About two hours previous experience with
the Reckoner; fair-to-middling typist; had written
From the collection of the Computer History Museum (www.computerhistory.org)
LINCOLN RECKONER: AN OPERATION-ORIENTED, ON-LINE FACILITY
and used two small programs in machine language;
no acquaintance with languages like ALGOL or
FORTRAN.
Communication-satellite problem that had arisen
in a study group in which he had participated. Considerable advance preparation in his office (amount
of time unknown) reading documents about the
Reckoner, doing algebra on the blackboard, and
writing out two processes on paper.
At the console, began by typing latitudes and longitudes of six cities around the globe. Assumed four
communication satellites in polar orbits: for simplicity, circular orbits all of the same altitude. Typed in
initial latitudes and longitudes of the satellites.
Defined a process that computed which satellites
were visible from which cities. Did not believe the
answers, and looked back through the results of intermediate calculations. Found he had gotten confused about whether sine or cosine of 60° was 1h.
Corrected the error and redid the computation.
Then printed out a 6 X 6 table with a row and a
column for every city, each entry being the number
of satellites through which the two cities were able
to communicate.
Defined another process, which advanced timei.e., rotated the earth by a certain number of
minutes and moved each satellite around in its orbit
by the same number of minutes. The process then
computed which satellites could be seen from which
cities and printed the 6 X 6 table.
Using this process, ran the simulated communication-system through most of a day's operation,
drawing conclusions about the way the initial placement of the satellites had affected the continuity of
communication.
Time: 1 hour and 45 minutes in a continuous
session, plus an unknown amount of advance preparation. The time is particularly impressive because
the Reckoner did not yet have routines for sines and
cosines; the user was continually calculating his way
around their absence.
Case C. Very experienced user, one of the designers
of the system; facile typist.
Was demonstrating the Reckoner to a prospective
user who had spent several hours the previous day
with a desk calculator finding how well
cos
7f'
(2: cos (j)
sin
(j
437
is approximated by sin (j in the interval 0 to 7f' /2.
To show how the computation would be done on
the Reckoner, typed a six-statement process, which
when given an array of numbers, (j, created a new
array, each of whose elements was derived from the
corresponding element of (j according to the expression
7f'
cos (- cos (j)
.
2
sm(j-----sin (j
(Note: This is a case where an algebraic language
would clearly have been helpful.)
Starting with the operation that creates a one-row
array of the integers from 1 to N, then multiplying
each integer by 7f'/2N, created an array THETA
that contained a couple of hundred numbers equally
spaced between 0 and '7T/2 (0 excluded). Applied
the process to this array and plotted the results
against the elements of THETA. Saw that the magnitude of the expression given above is maximum in
0.6; so asked for an expanded
the vicinity of ()
graph of the function in that region and read off the
value of the maximum as 0.0850
Time: Under 10 minutes, including time to state
the problem.
=
OPERATION-ORIENTED SYSTEMS
The Reckoner may be said to belong to a class of
systems that includes the OPS system 1 at Project
MAC, the MAP system,2 which is also at MAC, the
AMTRAN system 3 at the Marshall Space Flight
Center, the system on which Culler is working at
Santa Barbara,4 and the earlier Culler-Fried system,5
which influenced the design of the Reckoner in
many ways.
All of these systems have the following three features:
1. Automatic application of routines. Almost all
of the clerical work needed to perform an operation
-i.e., to apply a public routine-is done automatically. The system takes care of the location of the
data, the dimensions of arrays, and so forth. Ideally,
all the user has to do is somehow indicate the operation he wants to apply, the data to which he wants it
applied, and-perhaps-the way in which he will
identify the results when he wants to use them
again.
We say "perhaps" because some of the systems
have a sort of accumulator from which the typical
From the collection of the Computer History Museum (www.computerhistory.org)
438
PROCEEDINGS-FALL JOINT COMPUTER CONFERENCE, 1966
operation takes one of its operands and in which it
deposits the result; thus a result that is to be used
only in the next operation need not be stored away.
And we say "almost all the clerical work" because
the ideal can be approached but never achieved entirely.
2. Automatic retention of results in such a form
that they can be used as operands for other routines.
The results of operations are stored in such a fashion that they can be used later as inputs to other
operations-including operations that the user did
not have in mind when the results were obtained.
He need only specify the name or the button by
which he wants to identify a result; the system remembers where the result has been stored and automatically records the descriptive information that
will be needed if the result is to be used later as an
operand-e.g., the dimensions are recorded if the
result is an array of numbers.
3. Facilities for concatenation of routines. The
user can define a sequence of operations and then
use the sequence as he would use one of the primitive routines in the library. The new operation can
be used as part of another sequence, and so on.
We propose that the class of systems defined by
those three' characteristics be called "operationoriented." To the user, a process or a primitive routine is just an operation that he may perform on files
of data to produce graphs, printed tables, or new
files of data. In a different sense the word "operation" is appropriate from the designer's viewpoint,
too. These systems are oriented not toward the
preparation of routines, but toward the operation of
them. There may of course be provisions for writing
a new routine; but whether there are or not, convenience in the execution of existing routines is essential.
It should be emphasized that operation-oriented
systems need not look alike to the user. A system
whose library was specialized for the manipulation
of text would look very different from the present
Reckoner.
Appropriateness
The users for whom we are designing are
scientific and engineering research workers who may
not know much about programming, but who could
benefit from computational assistance, especially in
feeling through moderate amounts of data or
through relatively small theoretical calculations.
Operation-oriented systems seem appropriate for
that kind of user. The present system indicates it is
feasible to provide routines that can be combined to
perform most of the operations that the user wants;
so it is efficient for the system to emphasize the convenient use of routines from a library. A user who is
feeling his way through a problem often has no clear
idea of what he will do next; so it is efficient to
retain results in such a form that they can be used
as inputs to operations that were not foreseen when
the results were obtained. And as the user gets familiar with a problem, he generally thinks of the
calculations in larger and larger units; so it is
efficient to let him build processes that conform to
those units.
The advantages of an operation-oriented system
extend beyond the use of library routines. No matter
how complete the library may be, the user, or his
programming assistant, will sometimes have to write
new routines to perform operations that cannot be
satisfactorily contrived from the operations in the
library. Some operation-oriented systems therefore
provide access' to procedure-oriented languages like
FORTRAN and MAD, and a small procedure language is being added to the Reckoner. To be most
useful, a procedure language must allow one to
write routines that can be used like the routines in
the library. A new routine will generally be used a
number of times with different parameters or with
different sets of data; so convenience in applying it
is important. Furthermore, the programmer has less
work to do if he can write a routine that accepts the
results of library routines as inputs and stores its
results in such a form that library routines can employ them. He can concentrate on the crucial
aspects of the new operation, and can rely on the
library for preparation of the inputs, inspection of
the results, and so on.
Problem-oriented languages are also very useful
to the class of people for whom we are designing.
But if "problem-oriented" is understood in its strict
sense-oriented toward the problems of a particular
field like statistics or stress analysis-then these languages have limitations. A research scientist or engineer will inevitably push against the limits of any
problem language that can be provided for him.
After all, his job is partly to define new problems.
He will often want to step outside of the language
provided for him, apply 'his own processes, and then
From the collection of the Computer History Museum (www.computerhistory.org)
LINCOLN RECKONER: AN OPERATION-ORIENTED, ON-LINE FACILITY
go back. Thus problem languages, like procedure
languages, will be more useful if they are embedded in an operation-oriented system.
Indeed, it seems that the three characteristics we
have listed would be desirable in any work that a
researcher might want to do on-line-editing FORTRAN programs, making drawings, writing memoranda, and all the rest. We are almost prepared to
argue that any system for on-line use in a research
laboratory should be operation-oriented.
THE RECKONER FROM THE
PROGRAMMER'S POINT OF VIEW
This section will describe how the Reckoner is
put together and will comment on some decisions
that were made in designing it.
Services Provided by the Time-Sharing System
The Reckoner is time-shared and runs on TX-2,
the Laboratory's experimental computer. The TX-2
time-sharing system, which is called APEX, provides the Reckoner with three important services:
the input buffer, the directory of names, and the
stack of "maps." We shall just summarize them;
they have been described elsewhere. 6
The input stacker takes characters from the keyboard and puts them into a buffer area. The executive notifies the user's program when each statement
is complete-i.e., when the user has sent a carriage
return-but it continues to stack further statements,
up to the capacity of the buffer, whether the user's
program has processed the previous ones or not.
The executive maintains a private directory for
each user, and also a public directory of library routines and the like. In either case, the directory is a
ring-structured dictionary of names and definitions.
If the name refers to a single number, then the
definition consists simply of the number, but if the
name refers to a file (either a routine or a file of
data) then the definition includes an indication of
where the file may be found' and some of the descriptive information about it. The user's directory
can contain a name defined by a pointer to a definition in the public directory, and there can even be
names with no definitions (an important provision
in a system of this type). The user's programs are
not allowed to write in the directories, but they can
manipulate the private directory and inspect both
directories through calls to the'executive.
439
The executive also maintains the user's stack of
"maps." APEX provides each user with an "apparent computer" whose core memory is divided into
16 segments. A segment can contain only one file,
and a "map" is a list specifying the name of the file,
if any, that goes in each segment. A program may of
course get access to a subroutine by asking the executive to put the subroutine in a given segment on
the current map. But to make it easy for one routine
to use another when their memory-address requirements conflict, the calling routine may direct APEX
to put the new routine on a fresh map and transfer
control to the new routine, remembering the
specification of the old map. This process is called
"going up" to a new map, because the new map is
regarded as stacked on top of the old one. The reverse process, returning to the calling routine on the
next lower map, is called "peeling back." Common
to all maps is a special file, called the connector,
which is used for passing information between routines on different maps. By convention, the first register in the connector contains a pointer to the first
register that is not currently in use.
The input buffer, the directory, and the stack of
maps were built into the APEX executive partly for
reasons that depend on the nature of TX-2, and
partly because APEX was intended to support
operation-oriented systems. These three services
must be provided in some form, but they do not
necessarily have to be built into the time-sharing executive.
The Basic Translator
The execution of a library routine or a process
that the user has called from the keyboard begins
with the basic translator. It takes the statement out
of the buffer area, cleans up deleted characters and
so on, and then divides the statement into its component terms, which are usually separated by
spaces. Terms that are text-i.e., material between
the characters that are used as quotation marksare set aside, and terms that satisfy the rules for
numbers are converted to numbers in binary form.
Any term that is neither a quote nor a number is
assumed to be a name, and the basic translator asks
APEX to look it up. APEX looks first in the user's
private directory and then in the public directory,
and if the name does not appear in either directory,
inserts it in the private directory as a name that is
not yet defined. In either case APEX replies with a
From the collection of the Computer History Museum (www.computerhistory.org)
440
PROCEEDINGS-FALL JOINT COMPUTER CONFERENCE, 1966
pointer to the location of the name in one of the
directories.
The translator types an error-message if it is unable to interpret one of the terms as a quote or a
number and is unable to get the directory to accept
the term as a name. It also gives an error-message if
the first term in the statement is not the name of a
binary, executable routine.
If there are no errors, the translator puts into the
connector a calling sequence that is a term-for-term
translation of the statement the user typed: quotes
are given literally, numbers appear as actual binary
numbers, and names are represented by pointers to
the directory. Finally, the translator issues a "go up"
call to APEX, giving as a parameter of the call the
pointer to the first name in the statement, the name
of the routine that is to be executed.
The subroutines for number conversion and for
cleaning up the statement are fairly sizeable, but
otherwise the basic translator is rather simple. It can
be simple because its only responsibility is to construct a calling sequence and then go up. It balks at
going up to anything except an executable routine,
but aside from that, it does not know anything about
the nature of the routine that it is calling: it does
not know which terms the routine will use as inputs,
which it will use as names of outputs, or how many
terms are expected; it does not even know whether
it is calling a process or a library routine. Letting
the basic translator work in such ignorance is an
example of a policy that we shall call distributed
control. We shall come back to that later.
Library Routines
When a library routine has been entered by going
up to it, it gets its instructions from the calling sequence in the connector. If it is to operate on files of
data, it takes from the calling sequence pointers to
the names of the files and asks APEX to set them
up on the current map. It computes from the data
descriptions in those files the amount of space it will
need for working storage and for results, and it asks
APEX to create on the current map new files of the
appropriate sizes.
The routine then proceeds to do the computations
that are its main task, and inserts into the file (or
files) of results whatever descriptive information is
conventional for files of that type. It then takes from
the connector a pointer to the name that the results
are to have, and passes the pointer to APEX with a
request that the file be given this name. (The naming of the results is done last so that if the name of
an input is to be the same as the name for a result,
the name will not change meaning until the routine
is sure that it can finish successfully.) And finally,
the routine peels back to whatever called it.
Since the basic translator does not know the requirements of the routines that it calls, a library routine must check the acceptability of the terms that
appear in the calling sequence, and the acceptability
of the data to which they refer. It must see that the
sequence contains the right number of terms, that
the term for the result is a directory pointer and not
a number, that the dimensions of arrays on which it
is to operate are compatible, and so on. If any of
these legality checks fails, or if an error condition
like overflow is encountered during the computations themselves, then it types an appropriate errormessage.
Putting the legality checks into the library routines themselves was an almost inevitable decision.
The author of a new library routine should not have
to change programs that other people have written,
and he is the person who knows what his routine
can accept.
Building, Running, and Interrupting Processes
A process, like a routine, is an executable file.
Actually, only a small piece of it is executable, a
dozen instructions at the beginning, to which control
is transferred when the process is called. These few
instructions set up the process runner on the same
map and transfer control to it. The rest of the process consists of a list structure that the runner interprets.
The process builder can be used to construct a
new process, or to modify an existing one. It takes
each statement from the APEX buffer area and incorporates the statement into a simple list .structure,
assigning it a line number unless the user has
specified a number himself. These line numbers provide the necessary identification for replacing, inserting, and deleting lines, or for printing parts of a
process. The builder checks each line to see whether
it is an ordinary statement, a meta-command (e.g.
to delete aline), a jump statement, parameter line,
or an exit line. These· last three types are checked
for format, but other lines are inserted into the list
structure without any format checking. Dummy pa-
From the collection of the Computer History Museum (www.computerhistory.org)
LINCOLN RECKONER: AN OPERATION-ORIENTED, ON-LINE FACILITY
rameters and names beginning with periods are noted for special treatment at run time.
In handling an ordinary statement, the process
runner behaves very much like the basic translator.
It must construct temporary names' for names r that
begin with periods, and it must substitute the appropriate terms for dummy parameters, but aside from
that, it just builds the same calling sequence that the
basic translator would and issues a go-up request.
Like the basic translator, it does not know whether
it is calling a library routine or another process.
And like the basic translator, the runner makes
only those legality checks that cannot be left to the
routines that it calls. It makes the same checks that
the basic translator does, and it objects when it tries
to execute a line that contains a dummy parameter
for which no term was provided in the calling sequence by which the process itself was called. It also
checks jump lines to determine that the jump is to a
line that exists, and to determine that the relation in
a conditional jump is a relation between scalars.
And finally, when a routine that the runner has
called peels back, the runner checks to see whether
there is a flag indicating that the routine encountered an error condition. In this last case the routine
will have printed an error message, so the runner
does not. But in all cases the runner types the line
number and the name of the process it is running. It
then suspends the process and goes up to the basic
translator on the next map.
There are two other ways in which a process may
be suspended. The process itself may include a
statement that explicitly says go up to the basic
translator, and the user may press the interrupt button, which also has the effect of a go-up to the basic
translator. In any case, once the process has been
suspended, the user may use the basic translator to
call for processes and routines. He may also give a
special command that resumes the interrupted process, or a command that destroys the whole stack of
maps and returns control to the basic translator on
the lowest level.
New Primitive Routines
No matter how much effort is put into the public
library, the user will sometimes have to write a new
primitive routine, or get a programmer to do it for
him. A compiler for a small procedure-oriented language is therefore being written with the help of a
compiler-compiler 7 that is under development at the
441
Laboratory. The object programs are named in the
directory; they can be called in the normal manner
by the basic translator or the process runner, can
accept as inputs the files and numbers named in the
directory, and declare their results in the directoryall as a library routine would.
The language is rather simple: it has no provision
for text (i.e., literals), for in-out operations, for subroutines, or for calls to other routines. It has an
arithmetic statement, which is very like FORTRAN's, except that subscripts are actually typed as
subscripts; a begin statement, which simply marks
the beginning of a loop; an end statement, which
marks the end of a loop and shows the ranges over
which the variables in the loop are to run; a jump
statement, which transfers control to another statement in the same routine; a conditional statement,
which contains, first, a relation between two
numbers, and second, an ordinary arithmetic or
jump statement that is executed if the relation is
true; and a calling statement that shows which
names are to be treated as parameters and indicates
the order in which they will appear in the calling
sequence when the routine is used. There is also a
dimension statement that gives the dimensions of an
output array (the programmer does not declare the
dimensions of input arrays). The dimension statement is executable: it generates code that requests
APEX to create a file of a certain size.
An unusual feature of the language is a type of
expression called a "greatest allowable subscript."
For example, BETA,---2 means "the second dimension (i.e., the number of columns) of the array
named BETA." Expressions of this type may be
used freely in dimension statements, arithmetic
statements, and so on.
The seven statements listed above seem adequate
for the user who wants a routine for his own use,
but they are not really enough for the author of a
new routine for the public library. He will need
statements that can be used to check for error conditions-such as an undefined input term-and to
specify the messages that he wants printed when
various errors are detected.
Comments on the Distribution of Control
Perhaps the most common policy in designing a
system for on-line use is to put a compiler, or some
other language processor, in control of the calcula-
From the collection of the Computer History Museum (www.computerhistory.org)
442
PROCEEDINGS-FALL JOINT COMPUTER CONFERENCE, 1966
tions that the machine performs for the user. As has
been seen, we adopted a different policy, which may
be called a policy of distributed control.
The basic translator is a fairly simple routine, and
can scarcely be said to control the system. In fact,
no one routine is in charge. Consider for example
that the basic translator may pass control to a process, which sets up the process runner, which may
pass control to another process; the new process
again sets up the runner, which may now pass control to a library routine, which will peel back to the
runner; and so on. Throughout the whole chain of
events, no routine that puts control into another
map, either by going up or by peeling back, has any
information about the nature of the routine that will
take control. Thus, control is handed about among
modules that are remarkably independent. They are
held together only by the stack of maps, which
records the return path through the structure, and
by the directory, in which all results are entered so
that other modules can find them.
Even the control of the time-sharing system itself
is not vested in a translator in the usual way. APEX
has no command language and no command language translator. The functions that are usually
treated as commands-e.g., creating a synonym,
dropping a file, resuming a suspended process-are
all performed by small library routines that issue the
necessary calls to APEX. The use of these routines
is no different from the use of a matrix inversion
routine, either from the user's viewpoint, or from
the viewpoint of whatever routine calls them.
This way of handling commands is so neat and
straightforward that it has much to recommend it,
even in a system where control is not distributed in
the more thorough sense described above.
We should mention that some of our colleagues
feel there is one point at which we have not carried
the distribution of control far enough. A routine that
detects an error controls the delivery of the error
message to the user: it just hands the message to
APEX and requests that the message be printed. A
more flexible arrangement would be to have the routine pass an error indication to the routine that
called it. Then the calling routine could decide
whether to print the message or to take some other
action.
Advantages of Distributed Control
The virtues of distributed control arise mainly
from the severe modularity that it enforces. The
same advantages could no doubt be obtained by
other means, with enough persistence and enough
administrative effort, but with distributed control
they fall out naturally.
In the first place, there are advantages to the user.
The system not only is modular; it looks modular.
From the user's viewpoint the library routines are
tools with stable, fairly simple properties. When the
system comes to rest-i.e., when control is returned
to the basic translator-he can use those tools to
inspect his processes and his results before he embarks on another computational excursion. These
same tools are available when the system comes to
rest on a higher map after a process is suspended.
The users therefore have not felt any great need for
extra debugging tools.
Second, there are advantages to the system programmer. As usual, thorough modularity means that
the system is generalized by making additions, not
alterations. Even a new data-type-list structures,
for example-is strictly an additive matter. The programmer must write library routines that will create
and manipulate files of the new type, but beyond
that his only problem is administrative: he must
agree with other programmers on an identifying
code for files of the new type. He does not have to
make any change whatever in the existing software.
There is also a peculiar advantage to the author of a
new problem-oriented language. Assuming that the
necessary library routines already exist, he can write
a translator that just makes up a series of calls to
those routines.
And finally, we expect there will be some sociological advantages that might be summed up by Licklider's 8 phrase "coherent programming." He suggested that the software for an on-line system should
not be created at one stroke; instead, he envisioned
"a cooperative mode of programming through which
a community of creative people, most of them substantive users, but some of them professional system
programmers, might over a period of a few years
develop a software base" of the sort that substantive
users need. We would add that the basic requirement for coherence is this: The results of any operation must be ready for use as inputs to any other
operation, even when the operations are described in
different languages. This of course assumes that the
operations make sense-the system is allowed to
balk at computing the eigenvalues of a list of cities
-but with that restriction, we would say that a soft-
From the collection of the Computer History Museum (www.computerhistory.org)
LINCOLN RECKONER: AN OPERATION-ORIENTED, ON-LINE FACILITY
ware base is coherent only to the extent that it
meets this requirement.
An operation-oriented system, with the modularity enforced by distributed control, seems a natural
environment for coherence of just that kind .• Because adding to a modular structure is relatively
easy, a programmer will often find it economical to
write his program as a library routine, or as a translator that just calls on library routines. In any event,
he will generally be able to save himself work by
making his program compatible with the rest of the
system. If his program can use results produced by
other parts of the system, and if it stores its results
in such a form that other parts of the system can use
them, then the rest of the system will provide the
user with many auxiliary services that the programmer would otherwise have to provide himself. That
sort of incentive may be what is needed to make
coherent programming more common than it has
been. A chance to avoid extra work is often more
effective than social pressure.
APPENDIX
The following is a list of the 64 operations available in the Reckoner public library in the summer of
1966. (There are not, however, 64 distinct routines;
for example, sine and cosine are entrances to the
same routine.)
Data Shuffling in Two-dimensional
Arrays (14 operations)
Copy an array, transposing it
Copy an array, deleting certain rows
(columns)
Copy an array, saving only certain rows
(columns)
Copy an array, changing one element
Copy an array, replacing one row (column) by a given n X 1 or 1 X n array
Copy one element
Copy two or more arrays, and join the
copies to make a new large array
Copy a square array, replacing the diagonal by a given n X 1 or 1 X n array
Copy the diagonal and make it a 1 X n
or n X 1 array
Matrix Operations (6 operations)
Matrix multiplication
Matrix inversion
Rank
Determinant
Eigenvalues and eigenvectors of a symmetric matrix
Solution of the matrix equation AX == B
Signal Analysis (2 operations)
Fourier transform
Inverse Fourier transform
Basic Arithmetic on Arrays (12 operations)
Input (6 operations)
On two arrays
On one array
Add
Subtract
Multiply
Divide
Reciprocal
Square root
Log (base e or 10)
Antilog (base e or 10)
Sine
Cosine
Other Arithmetic on Arrays (8 operations)
Add a scalar to all elements
Multiply all elements by a scalar
Find sums of rows (columns)
Multiply each row (column) by corresponding element in a 1 X n or n X 1
array
Give largest and smallest elements
Find dimensions (number of rows, of
columns, etc.)
Enter an array (or single number) from
keyboard
Create a 1 X n array of the integers 1,
... ,n
Create an n X m array of zeros
Define a new process
Change a process
Output (9 operations)
Type a scalar, an array, a row, a column,
an element, text, or a process
Type dimensions of an array
Type largest and smallest elements
Type a synonym of a given name
Xerox listing of all names now defined
Plot on CRT (with or without automatic
choice of scales)
Turn plot off
From the collection of the Computer History Museum (www.computerhistory.org)
443
PROCEEDINGS-FALL JOINT COMPUTER CONFERENCE, 1966
444
Miscellaneous (7 operations)
Define a synonym for a name
Un define a name
Un define all names of an entity
Go up to the basic translator
Resume operation at the next lower map
Resume operation at the lowest map
Prepare for sign-off
ACKNOWLEDGMENTS
C. K. McElwain and L. G. Roberts, together with
some of the present authors, were responsible for
designing APEX to support operation-oriented systems. M. L. Goodman, E. A. Martin, and M. L.
Wendell were major contributors to the Reckoner
public library. M. A. Morfield, R. T. Mitchell, and,
especially, J. E. K. Smith contributed to the design
of the facility as seen by the user.
REFERENCES
1. M. Greenberger, et aI, "On-Line Computation
and Simulation: The OPS-3 System," MIT Press,
Cambridge, 1965.
2. R. Kaplow, S. L. Strong and J. W. Brackett,
"MAP: A System for On-Line Mathematical Analysis," MIT Project MAC Technical Report No. 24
(Jan. 1966).
3. L. J. Wood, et aI, "AMTRAN-Pushbutton
Route to Instant Mathematics?", Datamation (in
press) .
4. G. J. Culler, "The Computer-Aided Lecturer,"
Proc. Spring Joint Computer Conference, Spartan
Books, Washington, D.C., 1966.
5. - - , and B. D. Fried, "The TRW Two-Station, On-Line Scientific Computer: General Description," in M. Sass and W. D. Wilkinson (eds.), Computer Augmentation of Human Reasoning, Spartan
Books, Washington, D.C., 1965.
6. J. W. Forgie, "A Time- and Memory-Sharing
Executive Program for Quick-Response, On-Line
Applications," Proc. Fall Joint Computer Conference, Spartan Books, Washington, D.C., 1965.
7. J. A. Feldman, "A Formal Semantics for
Computer Languages and its Application in a Compiler-Compiler," Communications of the ACM, vol.
9 (Jan. 1966).
8. J. C. R. Licklider, "Languages for Specialization and Application of Prepared Procedures," in
Spiegel and Walker (eds.), Second Congress on the
Information System Sciences, Spartan Books, Washington, D.C., 1965.
From the collection of the Computer History Museum (www.computerhistory.org)
© Copyright 2026 Paperzz