At first every computer was designed and built by hand from scratch. The very first computers were programmed by connecting circuits together with patch cables. They were built with vacuum tubes as the transistor had not been invented yet. At that stage programming was primarily an electrical engineering task.
As the state of the art progressed, computers were designed and built by hand but there was an evolutionary resemblance between each successive unit. Some time around this time John Von Neuman came up with the idea of storing programs in the computers memory so that they could be easily modified. Programming, while still a very specialized task, became less hardware engineering and more similar to creating abstract mathematics. Programs were specific to the computers they were written for but the concepts were applicable to other models of computers.
As computer manufacturers started building computers with semiconductors instead of tubes and built many computers with essentially the same design, programmers started sharing small routines to do common tasks like reading from an input device or writing to an output device. These small routines evolved into operating systems.
Up until this time programs were written out on special forms and then converted into punched cards or paper tape with holes in it. These media were then fed to the computer to load the program. The program was run by computer operators who then collected any output generated and returned it along with the input media to the programmer. This was a time consuming process. As anyone who has ever written a program can tell you, the first attempt was rarely exactly as you intended it so there was a lot of head scratching done over memory dumps to try to figure out what went wrong and fix the program so that it could be submitted to run another time.
About this time, someone had a heretical idea. Instead of humans laboriously converting their programs into the numerical codes that the computer processed directly, they would write a program that would allow the programmer to write the program using a symbolic character representation where each symbolic word corresponded to the numeric code of the machine instruction. This representation was called assembly language and it sped up the development of programs by a factor of ten or so.
The next big change to programming was the development of the so called high level language. The first such language was called FORTRAN which was a word coined from the phrase FORmula TRANslation. It allowed engineers to specify programs in terms of the equations that they wanted to solve. This drastically improved productivity again, at least in so far as your program involved computing the solutions to equations.
The next high level language was called Lisp and it was derived from the phrase LISt Processing. Lisp was designed to facilitate the manipulation of abstract symbols. It was based on the idea of a list of symbols. Each symbol was called an atom. These atoms were arranged in lists enclosed in parenthesis. Lists could also contain other lists embedded within them so that when they were written out it seemed to the uninitiated like a lot of arbitrary words with parenthesis sprinkled liberally throughout.
The truth was, Lisp was a revolutionary advance in computing for a number of reasons. First and foremost, Lisp programs were written as lists, just like the data they operated on. This made it easy to write programs that read and wrote other programs. This made it possible for Lisp programs to think about programs in a rudimentary way. The study of Computer Science exploded in a frenzy of research about the kinds of things that could be represented and computed by a program and the research was largely done in Lisp at the key research centers.
Lisp was also one of the first programming languages that you programmed interactively. Typically the programmer sat at a console and was presented with a prompt, often a greater than character or a dollar sign. They would then type a Lisp expression in. The computer would read what they typed, evaluate it, and print the result. Then it would prompt for another line of input. This process was called the Read, Eval, Print Loop or REPL for short.
This style of programming encouraged the programmer to explore the problem domain piece meal instead of spending days designing solutions that might not work out when they were finally executed.
A third important attribute of Lisp programs were that they were largely independent of the details of the underlying hardware. Since they were typically stored in the human readable text source form, they could be easily moved from one type of computer to another. There was a bit of up front effort to implement the Lisp language on the new computer but the application programs moved over rather smoothly.
It is interesting to note that as later languages would introduce new features to the programming community it would be found that these features were pioneered by the early computer science researchers using Lisp.
In part two of this article, I will trace the evolution from Lisp to the World Wide Web. In the mean time, sweet dreams, don’t forget to tell the people you love that you love them, and most important of all, be kind.