Or, why long dead programming languages matter My motivation? Developer with an interest in PL design & implementation, paradigms, and history. Interested in questions like: is PL X suitable for task Y? Lisp’s 50th 2 years ago: Clojure talk at AJUG in 2008 Before this talk I hadn’t written any Algol; lots of Pascal Have you? Contribute anecdotes… This is a BIG topic. The amount of material available re: Algol is overwhelming Have done my best to extract the key points Algol: the Demon Star Algol: the ALgOrithmic Language IAL & Algol 60 Motivations Features and contributions Problems Implementations (then and now) The Children of Algol 60 “Algol-like” languages Algol is Dead: Long Live Algol The failure of Algol 60 The legacy of Algol 60 • • • • • Distance: 92.8 light years Orbital Period: 2.87 days Separation: 0.06 AU Variability recorded in 1667; probably known much earlier • Algol: Beta Persei • Arabic ra's al-ghūl from head of the demon/ogre/ghoul (Gorgon Medusa) • Also: Demon Star or Blinking Demon Algol images x 2 taken from this video: http://www.citizensky.org/forum/cs-video-and-planetarium-show-wtimothy-ferris “One member of the ALGOL committee ruefully noted that the name ALGOL, a contraction of Algorithmic Language, was also the name of a star whose English translation was “the Ghoul”. Whatever the reason for its ill-fate, ALGOL nonetheless was influential on later languages.” (Ceruzzi, p 95) “Lisp and Algol, are built around a kernel that seems as natural as a branch of mathematics.” (Metamagical Themas, Douglas Hofstadter) "Here is a language so far ahead of its time that it was not only an improvement on its predecessors but also on nearly all its successors.” (1980 Turing Award Lecture, C.A.R. Hoare) “Algol 60 lives on in the genes of Scheme and Pascal.” (SICP, Abelson & Sussman) begin integer result; integer procedure fact(n); value n; integer n; fact := if n = 0 then 1 else n * fact(n-1); result := fact(5); outinteger (1, result); outstring (1, "\n") end A familiar style for Pascal, Delphi, Modula-2 programmers. Zuse published details of an algorithmic language (Plankalkül) in 1948; did not receive much attention for decades. Rutihauser showed in-principle translation by computer of simple formulae and loop control in 1951. Boehm published method to translate algebraic formulae in computer notation in 1954. Similar attempts were made by Glennie (1952, UK) and Liapunov (1959, Russia). Adams and Laning presented an algorithmic language in 1954; first actually used (Europe). IBM released Fortran in 1954. Previously in the US, machine-specific assembly languages had been in use. An automatic computing symposium was held in 1955 in Darmstadt translation of algorithmic languages into machine code was discussed; Rutihauser and others stressed the need for a universal, machine-independent algorithmic language. Flow-Matic (1958): pre-cursor of COBOL; others by Grace Murray Hopper Math-Matic (1957): intended as improvement over Fortran; “Algol” contender By mid 1950’s, need for a universal machine independent PL was becoming apparent. Key issue: portability Passing of time aggravated problem: more PLs and more programs written in those languages GAMM (a European association for applied mathematics and mechanics) created a committee to look at developing such a language. In 1957, ACM and user groups such as SHARE formed a committee to “…study and recommend action for the creation of a universal programming language.” (MacLennan, p 99) In October 1957, GAMM proposed to ACM a joint effort. It should be as close as possible to standard mathematical notation and be readable without too much additional explanation. Naur thinks Algol (in general) failed on this count. It should be possible to use it for the description of computing processes in publications. It set the standard for at least next 30 years. Naur thinks this is the most frequent use of Algol 60. It should be mechanically translatable into machine programs. BNF and syntax-directed compiler tools IAL: International Algebraic Language Created in Zurich meeting over 8 days by 8 people. Many IBM users suggested abandoning Fortran, backing Algol IBM decided against that (understandably) Implementations for many dialects appeared, e.g. JOVIAL (by Jule’s Schwartz) Jule’s Own Version of the International Algebraic Language Still in use by USAF; for military aircraft embedded systems NELIAC: Navy Electronic Laboratories International Algol Compiler MAD: Michigan Algorithm Decoder (IBM, UNIVAC). Early dialects diminished value of universal language committing users to obsolete versions. “What can be said at all can be said clearly; and what we cannot talk about we must pass over in silence.” [Was sich überhaupt sagen läßt, läßt sich klar sagen; und wovon man nicht reden kann, darüber muß man schweigen.] (Ludwig Wittgensten, Tractatus Logico Philosophicus, 1921) Peter Naur (Editor) Backus, Bauer, Green, Katz, McCarthy, Perlis, Rutihauser, Samelson, Vauquois, Wegstein, van Wijngaarden, Woodger Formal syntax via Backus-Naur Form (BNF) Informal, semantics and examples for each syntactic construct Short: 15 pages! Common Lisp: ~450 pages In 1970s, Scheme paid tribute to Algol 60 with the Report on the Algorithmic Language Scheme BNF and formal (operational) semantics Started out short; even in its 6th revision, still only 90 pages 1958: Preliminary report on Algol, Zürich meeting intention was to collect comments/criticisms until final November 1959 design meeting; meant to be an interim report 1958: Informal meeting in Mainz (40 people) 1959: Copenhagen Algol implementation meeting led to creation of regular “Algol Bulletin” by Naur November 1959: Paris UNESCO Algol conference Backus presented syntax of Algol in a formal notation he had developed; based in part on his work in Fortran November 1959: ACM Committee considered comments sent to Communications of the ACM industry reps, e.g. SHARE, USE participated December 1959: Preparatory Boston meeting for 7 US delegates January 1960: International Algol meeting 7 European representatives selected from Paris various language changes discussed (see Perlis, 1974) May 1960: Report on the Algorithmic Language Algol 60 1962: Meeting in Rome to resolve remaining errors & ambiguities 1963: Revised Report on the Algorithmic Language Algol 60 Focus: machine independence and portability Strong, static typing (no implicits) integer, real, Boolean, arrays, string literals as parameters Block structure and compound statements Lexical (static) vs dynamic scope, Fortran COMMON Free vs fixed format due to input device variety: 80 or 90 column punched cards; Teletype; Punched paper tape; Forced programmers to think about code structure. By contrast: Fortran constrains format, Python enforces structure. Fortran format and I/O heavily influenced by IBM 704. Watson, 1975 Arrays Upper and lower limits can be specified Arbitrary number of dimensions Arbitrary subscript expressions Bounds checked at run-time Procedures Call-by-value and Call-by-name Recursion (in Lisp previously, not imperative PLs) Implicit use of stacks for scopes, activation records Generalised Fortran’s control constructs (if, do) own keyword ala static variables in C Backus-Naur Form to describe syntax Character set independence via different representations More on these later begin integer result; integer procedure fact(n); value n; integer n; begin if n = 0 then fact := 1 else fact := n * fact(n-1) end; result := fact(5); print(result) end begin integer result; integer procedure fact(n); value n; integer n; begin if n = 0 then fact := 1 else fact := n * fact(n-1) end; result := fact(5); print(result) end c Main program … c common arrays real*8 tvec,xvec common/datapts/tvec(1000000),xvec(1000000) … integer n … subroutine average c common arrays real*8 tvec,xvec common/datapts/tvec(1000000),xvec(1000000) … In dynamic scoping the meanings of statements and expressions are determined by the dynamic structure of the computations evolving in time. In lexical scoping the meanings of statements and expressions are determined by the static structure of the program. (MacLennan, p 119) Early versions of Lisp used dynamic scoping. Before version 5, Perl only had the local keyword which denoted dynamic scoping. Perl 5 added static scoping via my keyword. begin real procedure f(x); value x; real x; f := x**2 + 1; real procedure sum(n, m, inc); value n,m,inc; real n,m,inc; begin real s,x; s := 0; for x := n step inc until m do s := s + f(x); sum := s end; print(sum(1, 10, 0.1)) end begin real procedure sum(n, m, inc); value n,m,inc; real n,m,inc; begin real s,x; s := 0; for x := n step inc until m do s := s + f(x); sum := s end; begin real procedure f(x); value x; real x; f := x**2 + 1; print(sum(1, 10, 0.1)) end end begin real procedure helper(x); value x; real x; comment Does something expected for f; helper := x*x; real procedure f(n); value n; real n; f := helper(n) + 1; begin real procedure helper(x); value x; real x; comment Does something else…; helper := x*x*x; lexical: 26 print(f(5)) end end dynamic: 126 n x = ∑ i=1 1 — i begin comment Jensen's device using Algol 60's default Call-by-name parameter passing convention.; integer idx; real procedure sum (i, lo, hi, term); value lo, hi; integer i, lo, hi; real term; comment: term and i are passed by name; begin real temp; temp := 0; for i := lo step 1 until hi do temp := temp + term; sum := temp end; print(sum(idx, 1, 100, 1/idx)) end begin comment Inlined Jensen's Device.; integer lo, hi; integer idx; real sum; begin real temp; lo := 1; hi := 100; temp := 0; for idx := 1 step lo until hi do temp := temp + 1/idx; sum := temp end; print(sum); end It is as if the function’s formal parameters are bound to the named entity , e.g. term is bound to ‘1/idx’. The usual implementation is via so-called thunks. http://en.wikipedia.org/wiki/Thunk Parameterless, anonymous, unseen function. “…delays the computation of a function's argument, and the function forces the thunk to obtain the actual value.” Value returned is lvalue or rvalue depending upon whether on left or right hand side of an assignment. Thunks are still used by functional languages such as Haskell and Scala to implement code blocks whose invocation is to be delayed and re-evaluated. begin integer k; integer array A[1:5]; begin integer k; integer array A[1:5]; procedure inc2(i, j); integer i, j; begin i := i+1; j := j+1 end; k := 1; A[k] := 2; A[2] := 0; k := 1; A[k] := 2; A[2] := 0; inc2(k, A[k]); print(k, A[k]) end begin k := k+1; A[k] := A[k]+1 end; print(k, A[k]) end call-by-reference: 2 3 call-by-name: 2 1 begin integer i; integer array a[1:27]; procedure swap(x,y); integer x,y; begin integer temp; temp := x; x := y; y := temp end; a[1] := 27; i := 1; swap(i, a[i]) end begin integer temp; temp := 1; i := 27; a[27] := temp end; begin integer temp; temp := i; i := a[i]; a[i] := temp end; Instead of (i, a[1]) being swapped from (1, 27) to (27, 1) we get: (27, 27) since: i = 27 a[1] = 27 (unchanged) a[27] = 1 It is not possible to write a general swap procedure in Algol 60. Call-by-name (aka call-by-name) has odd side effects. Some combinations of parameters work. Algol 68 and other languages since Algol 60 have abandoned call-by-name in favour of the now familiar (and less expensive) call-by-reference in which the address of the object is passed. Thunks still have a role to play, as mentioned. “Peter Naur, then the editor of the Algol Bulletin, was surprised because Backus’s definition of Algol-58 did not agree with his interpretation of the Algol-58 report. He took this as an indication that a more precise method of describing syntax was required and prepared some samples of a variant of the Backus notation. As a result, this notation was adopted for the Algol-60 report…” (MacLennan, p 101) Chomsky type 0: recursively enumerable Chomsky type 1: context-sensitive Chomsky type 2: context-free Chomsky type 3: regular BNF corresponds directly to Chomsky type 2. Enabled mathematical analysis of PL grammar. Led to development of automatic parser generators e.g. META II used for VALGOL implementation later, extended BNF current tools, e.g. yacc, ANTLR <for list element> ::= <arithmetic expression> | <arithmetic expression> step <arithmetic expression> until <arithmetic expression> | <arithmetic expression> while <Boolean expression> <for list> ::= <for list element> | <for list> , <for list element> <for clause> ::= for <variable> := <for list> do <for statement> ::= <for clause> <statement> | <label>: <for statement> Examples of for loop syntax based upon BNF: for q:=1 step s until n do A[q]:=B[q] for i := 1 step 1 until 100 do begin x := i * 2; A[i] := x end for k:=1,V12 while V1<N do for days := 31, if leap then 29 else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 do Edsger Dijkstra wrote a letter to the editor of the March 1968 CACM that appeared as “GoTo-Statement Considered Harmful”: “For a number of years I have been familiar with the observation that the quality of programmers is a decreasing function of the frequency of go to statements in the programs they produce.” (Ceruzzi, p 100) This resulted in a “goto controversy” that lasted a few years. Added to the push towards Structured Programming. Diminished need for GOTO in Algol vs Fortran: Block structure Improved control constructs However, still present in Algol The expense of GOTO in Algol 60 GOTO statements can be complex, e.g. goto if a<b then exit else L[if b<=3 then b else 4]; Popping of activation records begin integer a, b; switch L := first, second, third, exit; inreal(0, a); inreal(0, b); goto if a<b then exit else L[if b<=3 then b else 4]; first: print("first"); goto exit; second: print("second"); goto exit; third: print("third"); goto exit; exit: end ERK! a: begin b: begin integer i; for i:=1 step 1 until 100 do begin outinteger(1, i*i); if i*i > 9 then goto exit end end; comment activation records must be popped to get here; worse if goto from within recursive procedure.; exit: outstring(1, "exited\n") end Now marst compiler (under GPL): generates C A60 interpreter In the decade following the Algol 60 Report Elliot Algol (Hoare, Dijkstra) Burroughs Algol VALGOL via META-II compiler-compiler http://en.wikipedia.org/wiki/ALGOL_60 Reference Language The working language of the committee The defining language; used in Algol 60 Report Character set chosen to illuminate Basic reference and guide for compiler builders Publication Language To be used for communicating algorithms Character set may be richer, may vary by country Hardware Representation Constrained by input device and character set of target computer Must specify rules to map from reference language See Algol 60 Report (Naur 1960) class Complex(x,y); real x,y; begin real re, im; real procedure RealPart; begin RealPart := re; end; … procedure Add(other); begin re := re + other.RealPart; … Algol was competing against Fortran in the scientific languages arena. European committee members more committed to cause of single universal language than US members who were engaged in other language projects. (Perlis, 1974) Nofre (2010) suggests Algol’s lack of adoption had more to do with diversity vs uniformity: UNCOL (SHARE sponsored) vs Algol 60 Lack of standard I/O or library writing capability fixed in Algol 68 (transput) Call-by-name problem fixed in Algol 68 (call-by-ref) Paucity of types, e.g. no complex type, strings as 2nd class citizens fixed in Simula, Algol 68 Baroque language features: for, switch/goto No separate compilation Fixed in Algol 68 (modules), Ada (packages), OO langs We’ve talked about Algol’s contributions: Language innovations Influenced most subsequent languages BNF, syntax directed compiler design Algol 60 as a publication language set the standard for years Also influenced machine architecture, e.g. dynamic allocation of storage for variables (ICL, Burroughs). Many processors today have machine instructions that cater for Algol-style activation records. But, experience with machine implementation was also leading this way. “Algol’s is the linguistic form most widely used in describing the new exotic algorithms…Where important new linguistic inventions have occurred, they have been imbedded usually within an Algol framework, e.g. records, classes, definitions of types and their operations,…,modules. Algol has become so ingrained in our thinking about programming that we almost automatically base investigations in abstract programming on an Algol representation to isolate, define, and explicate our ideas…It was a noble begin but never intended to be a satisfactory end.” (Perlis, 1978) Knuth, D., Backus Normal Form vs Backus Naur Form, CACM, Vol. 7, No. 12, Dec 1964 Naur, P. (Ed), Report on the Algorithmic Language ALGOL 60, CACM, Vol. 3 No. 5, May 1960, p 299–314 Naur, P. (Ed), Revised Report on the Algorithmic Language ALGOL 60, CACM, 1962 Naur, P., The European side of the last phase of the development of Algol 60, ACM SIGPLAN Notices, Vol. 13, No. 6, Aug 1976 Nofre, D., 2010, Unravelling Algol: US, Europe, and the creation of a Programming Language, IEEE Annals of the History of Computing Perlis, A.J., The American side of the development of Algol, Vol. 13, No. 8, Aug 1978 Ceruzzi, P., 2003, A History of Modern Computing, 2nd ed., MIT Press ACM Turing Award Lectures 1966–1985, AddisonWesley MacLennan, 1983, B.J., Principles of Programming Languages: Evaluation and Implementation, HRW Louden, K.C., 1993, Programming Languages: Principles and Practice, PWS-Kent Watson, 1975, An Introduction to Algol, Bell http://en.wikipedia.org/wiki/Algol http://stars.astro.illinois.edu/sow/algol.html http://www.constellationsofwords.com/stars/Algol.html http://en.wikipedia.org/wiki/ALGOL http://en.wikipedia.org/wiki/ALGOL_60 http://en.wikipedia.org/wiki/META_II http://www.citizensky.org/forum/cs-video-and-planetarium-show-wtimothy ferris http://rosettacode.org/wiki/ALGOL_68_Genie http://www.masswerk.at/algol60/algol60-sample.htm http://en.wikipedia.org/wiki/Thunk http://www.slideworld.com/slideshows.aspx/Algol-and-Haskell-ppt-775501 Whetstone Algol: http://www.mcjones.org/dustydecks/archives/2010/05/16/159/