CSE 230: Principles of Programming Languages
Notes on Chapter 1 of Stansifer (overview, introduction and history)

These notes are intended to supplement or correct material in the texts. They assume familiarity with the readings and are intentionally brief. Stansifer was published in 1995, so presumably written in 1994, and hence is a bit out of date. However, it takes a broad view of the role of programming languages and their study, focusing on principles behind design, and including historical and cultural information, as well as some underlying mathematics, all of which every well educated computer scientist should understand to some extent.

1.1 Much recent research suggests that natural language is not formal and cannot be formalized, due to its dependence on enormous amounts of background information and social context, each of which is highly variable, as well as difficult or impossible to formalize.

Findings from 1998 at the first pyramid show that Egyptian writing is at least as old as Summerian, and moreover, used a phonetic alphabet. Hence Stansifer's remarks on the evolution of the alphabet are out of date. The shards found there were records of tributes to the pharoah.

Recent archaelogical research also shows that forms of representation and calculation arose about 5,000 years ago, in ancient Egypt and Summeria, which needed ways to represent and calculate with numbers, largely for what we would now call accounting data. We would now also speak of data types and algorithms, rather than representation and calculation.

1.2 Work on the sociology of science shows that all mathematics has its origin in practical work; moreover, even today, mathematics research is largely driven by practical considerations; the notion of "pure mathematics" is somewhat of a myth, though a powerful one.

Perhaps Gottfried Leibniz the first to dream of a language for computation, though his dream went well beyond the programming languages that we have today since he envisioned using them for all forms of human reasoning, including legal reasoning. Leibniz also invented binary numbers, inspired by patterns found in the ancient Chinese book of divination, the I Ching. Leibniz is also famour for having invented the calculus, about the same time as, and independently from, Isaac Newton.

The novel The Difference Engine by William Gibson and Bruce Sterling contains an amusing fictional account of Babbage and Ada Augusta Lovelace, featuring giant steam driven computers (and much more).

1.4 Both Turing and von Neumann used assertions and invariants (which are the two main ideas) to prove correctness of flow chart programs, which they each introduced separately in the early 1940s. Turing also designed the first stored program electronic computer, although it was later redesigned and built by others in the UK. This information was secret until rather recently, because Turing's work was an important part of allied World War II efforts to break German and Japanese secret codes for messages. (There are several good books, and even a good play on Alan Turing's very interesting but rather sad life; the author of one of those books, Andrew Hodges, maintains a website devoted to the life of Turing, which includes a page on the play.)

1.5 The most important thing about FORTRAN was its excellent optimizating compiler; without this, assembly language programmers would never have changed their habits. ALGOL was designed by a (largely European) committee, and was the first langauge to have an international standard; it also introduced many important new features. PL/I failed mostly because it was too large. C was designed for systems programming, and cleverly combined high and low level features, based on ideas from BCPL, which was based on Christopher Strachey's very innovative CPL language. Simula, Smalltalk, and of course C++ all grew out of the imperative tradition, and the object oriented paradigm can be considered a variant of the imperative paradigm, as is rather clear from the quotations from Alan Kay given in Stansifer. Simula was developed by Kirstin Nygaard and Johan-Ole Dahl at the Norwegian Computing Center, and was originally designed for applications to simulation.

It is interesting to observe that the three major programming paradigms grew out of three major approaches to computable functions. Imperative (and object oriented) languages grew out of Turing machines, which also inspired the von Neumann architecture on which they usually run. The functional programming paradigm grew out of the lambda calculus approach to computable functions due to Alonzo Church, which was soon proved equivalent to the Turing machine approach. LISP was the first functional language, and it directly includes lambda abstraction and higher order functions. LISP was also the first interactive language, as well as the first to have garbage collection and to support symbolic computation; the latter was important for its intended applications to artificial intelligence, as was the fact that its programs were also written in its S-expression data structure. More recent functional programming languages are ML and Haskell; the latter takes its name from Haskell Curry, who introduced a variant of the lambda calculus which he called the combinatory calculus.

The so-called logic programming paradigm is related to a different notion of computability, having to do with the manipulation of algebraic terms, arising from work of Jacques Herbrand. (I say "so-called" because I think it is a misleading name, since its syntax is based on Horn clauses rather than full first order logic, and in any case, there are many many other logics than first order and Horn clause logic.) ML and Prolog both originated at Edinburgh from research on theorem proving and logic, in groups led by Robin Milner and Robert Kowalski, respectively, though these languages were much more fully developed elsewhere.

Advocates of so called structured programming railed against the infamous GOTO statement, claiming that it produced spaghetti code. Many today feel that unrestricted inheritance in object oriented programming is just as bad, especially in large systems that use dynamic binding and multiple inheritance.

The kind of modules found in Modula-3, Ada, C++ and ML have their origin in theoretical work by Goguen on abstract data types and general systems, and in the language designs for Clear (with Burstall) and OBJ (or so he says).

The most important ideas for personal computing came from Doug Englebart at SRI (then Stanford Research Institute): the mouse, windows, menus, and networking (recall that interaction came from LISP). Alan Kay at Xerox PARC popularized these ideas in Smalltalk, also adding icons; others at PARC developed the ethernet and the laser printer. Apple added very little to this mixture, and Microsoft has added nothing of intellectual significance (companies spend a lot on advertising their alleged creativity, often at the expense of the scientists who actually did the work).

The "Griswold" mentioned in connection with SNOBOL is the father of our own Prof. Bill Griswold.

An overview of the history of programming languages reveals a progressive increase in the level of abstraction: machine language; assembly language; (so called) "high level" languages like FORTRAN; and then ever more powerful features to support abstraction, including blocks, procedures, types, recursion, classes with inheritance, modules, specification, ... In general, this correlates with improvements in the underlying hardware. Perhaps machine language makes sense if your hardware is (relatively) small systems of gears and shafts, and your programs only compute repetative tables, as was the case for Babbage and Lovelace; assembly language perhaps makes sense if your hardware consists of (relatively) few vacuum tubes and your programs are for (relatively) small numerical tasks; but powerful mainframes and PCs running large programs require much more abstraction.

Perhaps the most glaring omission in Stansifer's book is Java, which did not come out until after this book was written. Because it is a language intended to be used over the internet, it has a very different character from the other languages discussed above; in particular, Java applets have the form of byte code, downloaded from a server to a client machine and run on there on a Java abstract machine; security is therefore an extremely important issue. Here, the hardware is the internet, not just a CPU with associated memory and peripherals.

To summarize a bit, we can see that there is a really close relationship between mathematics and programming. In particular, mathematicians were first inspired to build computers by the need to solve mathematical problems, and the architectures that they chose grew out of the mathematics that they knew. Moreover, the major programming paradigms correspond to different ways of defining the notion of computable function, and the historical trend of rising levels of abstraction also follows trends found in mathematics.

My Preliminary Essay on Comparative Programming Linguistics gives some further information related to the topics discussed above.


To CSE 230 homepage
To CSE 230 notes page
Maintained by Joseph Goguen
© 2000, 2001, 2002 Joseph Goguen
Last modified: Wed Feb 13 21:47:35 PST 2002