We are about to study the idea of a computational process.
They are abstract beings that inhabit computers.
As they evolve, processes manipulate other abstract things called data.
The evolution of a process is directed by a pattern of rules called a program.
People create programs to direct processes.
In effect, we conjure the spirits of the computer with our spells.
A computational process is indeed much like a
A computational process, in a correctly working computer, executes programs precisely and accurately.
Thus, like the sorcerer's apprentice, novice programmers must learn to understand and to anticipate the consequences of their
Fortunately, learning to program is considerably less dangerous than learning sorcery, because the spirits we deal with are conveniently contained in a secure way.
Real-world programming, however, requires care, expertise, and wisdom.
A small bug in a computer-aided design program, for example, can lead to the
Master software engineers have the ability to organize programs so that they can be reasonably sure that the resulting processes will perform the tasks intended. They can visualize the behavior of their systems in advance. They know how to structure programs so that unanticipated problems do not lead to catastrophic consequences, and when problems do arise, they can debug their programs. Well-designed computational systems, like well-designed automobiles or nuclear reactors, are designed in a modular manner, so that the parts can be constructed, replaced, and debugged separately.
Programming in Lisp
We need an appropriate language for describing processes, and we will use for this purpose the programming language Lisp.
Just as our everyday thoughts are usually expressed in our natural language like English, and descriptions of quantitative phenomena are expressed with mathematical notations, our procedural thoughts will be expressed in Lisp.
Lisp was invented in the late 1950s as a formalism for reasoning about the use of certain kinds of logical expressions, called recursion equations, as a model for computation.
The language was Recursive Functions of Symbolic Expressions and Their Computation by Machine
.
Despite its
Lisp was not the product of a concerted design effort.
Instead, it evolved informally in an experimental manner in response to users' needs and to pragmatic implementation considerations.
Lisp's informal evolution has continued through the years, and the community of Lisp users has traditionally resisted attempts to official
definition of the language.
This evolution, together with the flexibility and elegance of the initial conception, has enabled Lisp, which is the 2nd oldest language in widespread use today (1st is Fortran), to continually adapt to encompass the most modern ideas about program design.
Thus, Lisp is by now a family of dialects, which, while sharing most of the original features, may differ from one another in significant ways.
The dialect of Lisp used in this book is called
MacLisp (Moon 1978; Pitman 1983), developed at the MIT Project MAC, and
Interlisp (Teitelman 1974), developed at Bolt Beranek and Newman Inc. and the Xerox Palo Alto Research Center.
Portable Standard Lisp (Hearn 1969; Griss 1981) was a Lisp dialect designed to be easily portable between different machines.
MacLisp spawned a number of subdialects, such as
Franz Lisp, which was developed at the University of California at Berkeley, and
Zetalisp (Moon 1981), which was based on a special-purpose processor designed at the MIT Artificial Intelligence Laboratory to run Lisp very efficiently.
The Lisp dialect used in this book, called Scheme (Steele 1975), was invented in 1975 by Guy Lewis Steele Jr. and Gerald Jay Sussman of the MIT Artificial Intelligence Laboratory
and later reimplemented for instructional use at MIT.
Scheme became an IEEE standard in 1990 (IEEE 1990).
The Common Lisp dialect (Steele 1982, Steele 1990) was developed by the Lisp community to combine features from the earlier Lisp dialects to make an industrial standard for Lisp.
Common Lisp became an ANSI standard in 1994 (ANSI 1994).
Because of its experimental character and its emphasis on symbol manipulation, Lisp was at first very inefficient for numerical computations, at least in comparison with Fortran.
Over the years, however, Lisp compilers have been developed that translate programs into machine code that can perform numerical computations reasonably efficiently.
And for
If Lisp is not a mainstream language, why are we using it as the framework for our discussion of programming? Because the language possesses unique features that make it an excellent medium for studying important programming constructs and data structures and for relating them to the linguistic features that support them.
The most significant of these features is the fact that Lisp descriptions of processes, called procedures, can themselves be represented and manipulated as Lisp data.
The importance of this is that there are passive
data and active
processes