ALGOL
View on Wikipedia
| ALGOL | |
|---|---|
A 1965 manual for ALGOL-20 | |
| Paradigm | Procedural, imperative, structured |
| Family | ALGOL |
| Designed by | Bauer, Bottenbruch, Rutishauser, Samelson, Backus, Katz, Perlis, Wegstein, Naur, Vauquois, van Wijngaarden, Woodger, Green, McCarthy |
| First appeared | 1958 |
| Typing discipline | Static, strong |
| Scope | Lexical |
| Influenced | |
| Most subsequent imperative languages (including so-called ALGOL-like languages) e.g. PL/I, Simula, Pascal, C and Scheme | |
ALGOL (/ˈælɡɒl, -ɡɔːl/; short for "Algorithmic Language")[1] is a family of imperative computer programming languages originally developed in 1958. ALGOL heavily influenced many other languages and was the standard method for algorithm description used by the Association for Computing Machinery (ACM) in textbooks and academic sources for more than thirty years.[2]
In the sense that the syntax of most modern languages is "Algol-like",[3] it was arguably more influential than three other high-level programming languages among which it was roughly contemporary: FORTRAN, Lisp, and COBOL.[4] It was designed to avoid some of the perceived problems with FORTRAN and eventually gave rise to many other programming languages, including PL/I, Simula, BCPL, B, Pascal, Ada, and C.
ALGOL introduced code blocks and the begin...end pairs for delimiting them. It was also the first language implementing nested function definitions with lexical scope. Moreover, it was the first programming language which gave detailed attention to formal language definition and through the Algol 60 Report introduced Backus–Naur form, a principal formal grammar notation for language design.
There were three major specifications, named after the years they were first published:
- ALGOL 58 – originally proposed to be called IAL, for International Algebraic Language.
- ALGOL 60 – first implemented as X1 ALGOL 60 in 1961. Revised 1963.[5][6][7]
- ALGOL 68 – introduced new elements including flexible arrays, slices, parallelism, operator identification. Revised 1973.[8]
ALGOL 68 is substantially different from ALGOL 60 and was not well received,[according to whom?] so reference to "Algol" is generally understood to mean ALGOL 60 and its dialects.[citation needed]
History
[edit]ALGOL was developed jointly by a committee of European and American computer scientists in a meeting in 1958 at the Swiss Federal Institute of Technology in Zurich (cf. ALGOL 58).[9] It specified three different syntaxes: a reference syntax, a publication syntax, and an implementation syntax, syntaxes that permitted it to use different keyword names and conventions for decimal points (commas vs periods) for different languages.[5]
ALGOL was used mostly by research computer scientists in the United States and in Europe; commercial applications were hindered by the absence of standard input/output facilities in its description, and the lack of interest in the language by large computer vendors (other than Burroughs Corporation).[10] ALGOL 60 did however become the standard for the publication of algorithms and had a profound effect on future language development.[10]

John Backus developed the Backus normal form method of describing programming languages specifically for ALGOL 58. It was revised and expanded by Peter Naur for ALGOL 60, and at Donald Knuth's suggestion renamed Backus–Naur form.[11]
Peter Naur: "As editor of the ALGOL Bulletin I was drawn into the international discussions of the language and was selected to be member of the European language design group in November 1959. In this capacity I was the editor of the ALGOL 60 report, produced as the result of the ALGOL 60 meeting in Paris in January 1960."[12]
The following people attended the meeting in Paris (from 11 to 16 January):[5]
- Friedrich Ludwig Bauer, Peter Naur, Heinz Rutishauser, Klaus Samelson, Bernard Vauquois, Adriaan van Wijngaarden, and Michael Woodger (from Europe)
- John Warner Backus, Julien Green, Charles Katz, John McCarthy, Alan Jay Perlis, and Joseph Henry Wegstein (from the US).
Alan Perlis gave a vivid description of the meeting: "The meetings were exhausting, interminable, and exhilarating. One became aggravated when one's good ideas were discarded along with the bad ones of others. Nevertheless, diligence persisted during the entire period. The chemistry of the 13 was excellent."[13]
Legacy
[edit]A significant contribution of the ALGOL 58 Report was to provide standard terms for programming concepts: statement, declaration, type, label, primary, block, and others.[10]
ALGOL 60 inspired many languages that followed it. Tony Hoare remarked: "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."[14] The Scheme programming language, a variant of Lisp that adopted the block structure and lexical scope of ALGOL, also adopted the wording "Revised Report on the Algorithmic Language Scheme" for its standards documents in homage to ALGOL.[15]
Properties
[edit]This section needs additional citations for verification. (February 2024) |
ALGOL 60 as officially defined had no I/O facilities; implementations defined their own in ways that were rarely compatible with each other. In contrast, ALGOL 68 offered an extensive library of transput (input/output) facilities.
ALGOL 60 allowed for two evaluation strategies for parameter passing: the common call-by-value, and call-by-name. Call-by-name has certain effects in contrast to call-by-reference. For example, without specifying the parameters as value or reference, it is impossible to develop a procedure that will swap the values of two parameters if the actual parameters that are passed in are an integer variable and an array that is indexed by that same integer variable.[16] Think of passing a pointer to swap(i, A[i]) in to a function. Now that every time swap is referenced, it is reevaluated. Say i := 1 and A[i] := 2, so every time swap is referenced it will return the other combination of the values ([1,2], [2,1], [1,2] and so on). A similar situation occurs with a random function passed as actual argument.
Call-by-name is known by many compiler designers for the interesting "thunks" that are used to implement it. Donald Knuth devised the "man or boy test" to separate compilers that correctly implemented "recursion and non-local references." This test contains an example of call-by-name.
ALGOL 68 was defined using a two-level grammar formalism invented by Adriaan van Wijngaarden and which bears his name. Van Wijngaarden grammars use a context-free grammar to generate an infinite set of productions that will recognize a particular ALGOL 68 program; notably, they are able to express the kind of requirements that in many other programming language standards are labelled "semantics" and have to be expressed in ambiguity-prone natural language prose, and then implemented in compilers as ad hoc code attached to the formal language parser.
Examples and portability
[edit]This section needs expansion with: further annotation indicating sources of code samples, as Wikipedia disallows presentation of individual editor creations or other original research. You can help by adding to it. (February 2024) |
Code sample comparisons
[edit]ALGOL 60
[edit](The way the bold text has to be written depends on the implementation, e.g. 'INTEGER'—quotation marks included—for integer. This is known as stropping.)
procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
value n, m; array a; integer n, m, i, k; real y;
comment The absolute greatest element of the matrix a, of size n by m,
is copied to y, and the subscripts of this element to i and k;
begin
integer p, q;
y := 0; i := k := 1;
for p := 1 step 1 until n do
for q := 1 step 1 until m do
if abs(a[p, q]) > y then
begin y := abs(a[p, q]);
i := p; k := q
end
end Absmax
Here is an example of how to produce a table using Elliott 803 ALGOL.[17]
FLOATING POINT ALGOL TEST' BEGIN REAL A,B,C,D' READ D' FOR A:= 0.0 STEP D UNTIL 6.3 DO BEGIN PRINT PUNCH(3),££L??' B := SIN(A)' C := COS(A)' PRINT PUNCH(3),SAMELINE,ALIGNED(1,6),A,B,C' END END'
ALGOL 68
[edit]The following code samples are ALGOL 68 versions of the above ALGOL 60 code samples.
ALGOL 68 implementations used ALGOL 60's approaches to stropping. In ALGOL 68's case tokens with the bold typeface are reserved words, types (modes) or operators.
proc abs max = ([,]real a, ref real y, ref int i, k)real:
comment The absolute greatest element of the matrix a, of size ⌈a by 2⌈a
is transferred to y, and the subscripts of this element to i and k; comment
begin
real y := 0; i := ⌊a; k := 2⌊a;
for p from ⌊a to ⌈a do
for q from 2⌊a to 2⌈a do
if abs a[p, q] > y then
y := abs a[p, q];
i := p; k := q
fi
od
od;
y
end # abs max #
Note: lower (⌊) and upper (⌈) bounds of an array, and array slicing, are directly available to the programmer.
floating point algol68 test:
(
real a,b,c,d;
# printf – sends output to the file stand out. #
# printf($p$); – selects a new page #
printf(($pg$,"Enter d:"));
read(d);
for step from 0 while a:=step*d; a <= 2*pi do
printf($l$); # $l$ - selects a new line. #
b := sin(a);
c := cos(a);
printf(($z-d.6d$,a,b,c)) # formats output with 1 digit before and 6 after the decimal point. #
od
)
Timeline: Hello world
[edit]The variations and lack of portability of the programs from one implementation to another is easily demonstrated by the classic hello world program.[citation needed]
ALGOL 58 (IAL)
[edit]ALGOL 58 had no I/O facilities.
ALGOL 60 family
[edit]Since ALGOL 60 had no I/O facilities, there is no portable hello world program in ALGOL. The next three examples are in Burroughs Extended Algol. The first two direct output at the interactive terminal they are run on. The first uses a character array, similar to C. The language allows the array identifier to be used as a pointer to the array, and hence in a REPLACE statement.
BEGIN
FILE F(KIND=REMOTE);
EBCDIC ARRAY E[0:11];
REPLACE E BY "HELLO WORLD!";
WRITE(F, *, E);
END.
A simpler program using an inline format:
BEGIN
FILE F(KIND=REMOTE);
WRITE(F, <"HELLO WORLD!">);
END.
An even simpler program using the Display statement. Note that its output would end up at the system console ('SPO'):
BEGIN DISPLAY("HELLO WORLD!") END.
An alternative example, using Elliott Algol I/O is as follows. Elliott Algol used different characters for "open-string-quote" and "close-string-quote", represented here by ‘ and ’ .
program HiFolks;
begin
print ‘Hello world’
end;
Below is a version from Elliott 803 Algol (A104). The standard Elliott 803 used five-hole paper tape and thus only had upper case. The code lacked any quote characters so £ (UK Pound Sign) was used for open quote and ? (Question Mark) for close quote. Special sequences were placed in double quotes (e.g£. £L?? produced a new line on the teleprinter).
HIFOLKS'
BEGIN
PRINT £HELLO WORLD£L??'
END'
The ICT 1900 series Algol I/O version allowed input from paper tape or punched card. Paper tape 'full' mode allowed lower case. Output was to a line printer. The open and close quote characters were represented using '(' and ')' and spaces by %.[18]
'BEGIN'
WRITE TEXT('('HELLO%WORLD')');
'END'
ALGOL 68
[edit]ALGOL 68 code was published with reserved words typically in lowercase, but bolded or underlined.
begin printf(($gl$,"Hello, world!")) end
In the language of the "Algol 68 Report" the input/output facilities were collectively called the "Transput".
Timeline of ALGOL special characters
[edit]The ALGOLs were conceived at a time when character sets were diverse and evolving rapidly; also, the ALGOLs were defined so that only uppercase letters were required.
1960: IFIP – The Algol 60 language and report included several mathematical symbols which are available on modern computers and operating systems, but, unfortunately, were unsupported on most computing systems at the time. For instance: ×, ÷, ≤, ≥, ≠, ¬, ∨, ∧, ⊂, ≡, ␣ and ⏨.
1961 September: ASCII – The ASCII character set, then in an early stage of development, had the \ (Back slash) character added to it in order to support ALGOL's Boolean operators /\ and \/.[19]
1962: ALCOR – This character set included the unusual "᛭" runic cross[20] character for multiplication and the "⏨" Decimal Exponent Symbol[21] for floating point notation.[22][23][24]
1964: GOST – The 1964 Soviet standard GOST 10859 allowed the encoding of 4-bit, 5-bit, 6-bit and 7-bit characters in ALGOL.[25]
1968: The "Algol 68 Report" – used extant ALGOL characters, and further adopted →, ↓, ↑, □, ⌊, ⌈, ⎩, ⎧, ○, ⊥, and ¢ characters which can be found on the IBM 2741 keyboard with typeball (or golf ball) print heads inserted (such as the APL golf ball). These became available in the mid-1960s while ALGOL 68 was being drafted. The report was translated into Russian, German, French, and Bulgarian, and allowed programming in languages with larger character sets, e.g., Cyrillic alphabet of the Soviet BESM-4. All ALGOL's characters are also part of the Unicode standard and most of them are available in several popular fonts.
2009 October: Unicode – The ⏨ (Decimal Exponent Symbol) for floating point notation was added to Unicode 5.2 for backward compatibility with historic Buran programme ALGOL software.[26]
ALGOL implementations
[edit]To date there have been at least 70 augmentations, extensions, derivations and sublanguages of Algol 60.[27]
| Name | Year | Author | Country | Description | Target CPU |
|---|---|---|---|---|---|
| ZMMD-implementation | 1958 | Friedrich L. Bauer, Heinz Rutishauser, Klaus Samelson, Hermann Bottenbruch | implementation of ALGOL 58 | Z22 (later Zuse's Z23 was delivered with an Algol 60 compiler)[28] | |
| X1 ALGOL 60 | 1960 August[29] | Edsger W. Dijkstra and Jaap A. Zonneveld | First implementation of ALGOL 60[30] | Electrologica X1 | |
| Elliott ALGOL | 1960s | C. A. R. Hoare | Subject of the 1980 Turing Award Lecture[31] | Elliott 803, Elliott 503, Elliott 4100 series | |
| JOVIAL | 1960 | Jules Schwartz | A DOD HOL prior to Ada | Various (see article) | |
| Burroughs Algol (Several variants) |
1961 | Burroughs Corporation (with participation by Hoare, Dijkstra, and others) | Basis of the Burroughs (and now Unisys MCP based) computers | Burroughs Large Systems and their midrange also. | |
| Case ALGOL | 1961 | Case Institute of Technology[32] | Simula was originally contracted as a simulation extension of the Case ALGOL | UNIVAC 1107 | |
| GOGOL | 1961 | William M. McKeeman | For ODIN time-sharing system[33] | PDP-1 | |
| RegneCentralen ALGOL | 1961 | Peter Naur, Jørn Jensen | Implementation of full Algol 60 | DASK at Regnecentralen | |
| Dartmouth ALGOL 30 | 1962 | Thomas Eugene Kurtz et al. | LGP-30 | ||
| USS 90 Algol | 1962 | L. Petrone | |||
| ALGOL 60 | 1962 | Bernard Vauquois, Louis Bolliet[34] | Institut d'Informatique et Mathématiques Appliquées de Grenoble (IMAG) and Compagnie des Machines Bull | Bull Gamma 60 | |
| Algol Translator | 1962 | G. van der Mey and W.L. van der Poel | Staatsbedrijf der Posterijen, Telegrafie en Telefonie | ZEBRA | |
| Kidsgrove Algol | 1963 | F. G. Duncan | English Electric Company KDF9 | ||
| VALGOL | 1963 | Val Schorre | A test of the META II compiler compiler | ||
| Whetstone | 1964 | Brian Randell and L. J. Russell | Atomic Power Division of English Electric Company. Precursor to Ferranti Pegasus, National Physical Laboratories ACE and English Electric DEUCE implementations. | English Electric Company KDF9 | |
| NU ALGOL | 1965 | UNIVAC | |||
| ALGEK | 1965 | АЛГЭК, based on ALGOL-60 and COBOL support, for economical tasks | Minsk-22 | ||
| ALGOL W | 1966 | Niklaus Wirth | Proposed successor to ALGOL 60 | IBM System/360 | |
| MALGOL | 1966 | publ. A. Viil, M Kotli & M. Rakhendi, | Minsk-22 | ||
| ALGAMS | 1967 | GAMS group (ГАМС, группа автоматизации программирования для машин среднего класса), cooperation of Comecon Academies of Science | Comecon | Minsk-22, later ES EVM, BESM | |
| ALGOL/ZAM | 1967 | Polish ZAM computer | |||
| Simula 67 | 1967 | Ole-Johan Dahl and Kristen Nygaard | Algol 60 with classes | UNIVAC 1107 | |
| Triplex-ALGOL Karlsruhe | 1967/1968 | Karlsruhe, |
ALGOL 60 (1963) with triplex numbers for interval arithmetic | [35] | |
| Chinese Algol | 1972 | Chinese characters, expressed via the Symbol system | |||
| DG/L | 1972 | DG Eclipse family of Computers | |||
| S-algol | 1979 | Ron Morrison | Addition of orthogonal datatypes with intended use as a teaching language | PDP-11 with a subsequent implementation on the Java VM |
The Burroughs dialects included special Bootstrapping dialects such as ESPOL and NEWP. The latter is still used for Unisys MCP system software.
See also
[edit]References
[edit]- ^ The name of this language family is sometimes given in mixed case (Algol 60 Archived 25 June 2007 at the Wayback Machine), and sometimes in all uppercase (ALGOL68 Archived 13 September 2014 at the Wayback Machine). For simplicity this article uses ALGOL.
- ^ Collected Algorithms of the ACM Archived 17 October 2011 at Wikiwix Compressed archives of the algorithms. ACM.
- ^ O'Hearn, P. W.; Tennent, R. D. (September 1996). "Algol-like languages, Introduction". Archived from the original on 14 November 2011.
- ^ "The ALGOL Programming Language" Archived 6 October 2016 at the Wayback Machine, University of Michigan-Dearborn
- ^ a b c Backus, John Warner; Bauer, Friedrich Ludwig; Green, Julien; Katz, Charles; McCarthy, John; Naur, Peter; Perlis, Alan Jay; Rutishauser, Heinz; Samelson, Klaus; Vauquois, Bernard; Wegstein, Joseph Henry; van Wijngaarden, Adriaan; Woodger, Michael (May 1960). Naur, Peter (ed.). "Report on the Algorithmic Language ALGOL 60". Communications of the ACM. 3 (5). Copenhagen, Denmark: 299–314. doi:10.1145/367236.367262. ISSN 0001-0782. S2CID 278290.
- ^ "Revised Report on the Algorithmic Language Algol 60". 1963. Archived from the original on 25 June 2007. Retrieved 8 June 2007.
- ^ "An ALGOL 60 Translator for the X1" (PDF). 1961. Archived (PDF) from the original on 9 October 2022. Retrieved 7 January 2021.
- ^ "Revised Report on the Algorithmic Language ALGOL 68" (PDF). 1973. Archived (PDF) from the original on 13 September 2014. Retrieved 13 September 2014.
- ^ "History of ALGOL — Software Preservation Group". www.softwarepreservation.org. Retrieved 14 March 2024.
- ^ a b c Bemer, Bob. "A Politico-Social History of Algol" (PDF). Computer History Museum. Retrieved 9 August 2024.
- ^ Knuth, Donald E. (1964). "Backus Normal Form vs Backus Naur Form". Communications of the ACM. 7 (12): 735–736. doi:10.1145/355588.365140. S2CID 47537431.
- ^ ACM Award Citation: Peter Naur Archived 2 April 2012 at Archive-It, 2005
- ^ Perlis, Alan J (1978). "The American side of the development of ALGOL". History of programming languages. pp. 75–91. doi:10.1145/800025.1198352. ISBN 0-12-745040-8 – via dl.acm.org.
- ^ "Hints on Programming Language Design" Archived 15 September 2009 at the Wayback Machine, C.A.R. Hoare, December 1973. Page 27. (This statement is sometimes erroneously attributed to Edsger W. Dijkstra, also involved in implementing the first ALGOL 60 compiler.)
- ^ Dybvig, R. K.; et al. Rees, Jonathan; Clinger, William; Abelson, Hal (eds.). "Revised(3) Report on the Algorithmic Language Scheme, (Dedicated to the Memory of ALGOL 60)". Archived from the original on 14 January 2010. Retrieved 20 October 2009.
- ^ Aho, Alfred V.; Sethi, Ravi; Ullman, Jeffrey D. (1986). Compilers: Principles, Techniques, and Tools (1st ed.). Addison-Wesley. ISBN 0-201-10194-7., Section 7.5, and references therein
- ^ "803 ALGOL" Archived 29 May 2010 at the Wayback Machine, the manual for Elliott 803 ALGOL
- ^ "ICL 1900 series: Algol Language". ICL Technical Publication 3340. 1965.
- ^ How ASCII Got Its Backslash Archived 11 July 2014 at the Wayback Machine, Bob Bemer
- ^ iron/runic cross
- ^ Decimal Exponent Symbol
- ^ Baumann, R. (October 1961). "ALGOL Manual of the ALCOR Group, Part 1" [ALGOL Manual of the ALCOR Group]. Elektronische Rechenanlagen (in German): 206–212.
- ^ Baumann, R. (December 1961). "ALGOL Manual of the ALCOR Group, Part 2" [ALGOL Manual of the ALCOR Group]. Elektronische Rechenanlagen (in German). 6: 259–265.
- ^ Baumann, R. (April 1962). "ALGOL Manual of the ALCOR Group, Part 3" [ALGOL Manual of the ALCOR Group]. Elektronische Rechenanlagen (in German). 2.
- ^ "GOST 10859 standard". Archived from the original on 16 June 2007. Retrieved 5 June 2007.
- ^ Broukhis, Leonid (22 January 2008). "Revised proposal to encode the decimal exponent symbol" (PDF). www.unicode.org. ISO/IEC JTC 1/SC 2/WG 2. Archived (PDF) from the original on 31 July 2015. Retrieved 24 January 2016.
This means that the need to transcode GOST-based software and documentation can still arise: legacy numerical algorithms (some of which may be of interest, e.g. for the automatic landing of the Buran shuttle ...) optimized for the non-IEEE floating point representation of BESM-6 cannot be simply recompiled and be expected to work reliably, and some human intervention may be necessary.
- ^ "The Encyclopedia of Computer Languages". Archived from the original on 27 September 2011. Retrieved 20 January 2012.
- ^ Computer Museum History Archived 20 August 2010 at the Wayback Machine, Historical Zuse-Computer Z23, restored by the Konrad Zuse Schule in Hünfeld, for the Computer Museum History Center in Mountain View (California) US
- ^ Daylight, E. G. (2011). "Dijkstra's Rallying Cry for Generalization: the Advent of the Recursive Procedure, late 1950s – early 1960s". The Computer Journal. 54 (11): 1756–1772. CiteSeerX 10.1.1.366.3916. doi:10.1093/comjnl/bxr002. Archived from the original on 12 March 2013.
- ^ Kruseman Aretz, F.E.J. (30 June 2003). "The Dijkstra-Zonneveld ALGOL 60 Compiler for the Electrologica X1". Software Engineering (PDF). History of Computer Science. Amsterdam: Centrum Wiskunde & Informatica. Archived (PDF) from the original on 4 March 2016.
- ^ Hoare, Antony (1980). "The Emperor's Old Clothes". Communications of the ACM. 24 (2): 75–83. doi:10.1145/358549.358561.
- ^ Koffman, Eliot. "All I Really Need to Know I Learned in CS1" (PDF). Archived from the original (PDF) on 12 October 2012. Retrieved 20 May 2012.
- ^ "GOGOL – PDP-1 Algol 60 (Computer Language)". Online Historical Encyclopaedia of Programming Languages. Archived from the original on 2 February 2018. Retrieved 1 February 2018.
- ^ Mounier-Kuhn, Pierre (2014). "Algol in France: From Universal Project to Embedded Culture". IEEE Annals of the History of Computing. 36 (4): 6–25. Bibcode:2014IAHC...36d...6M. doi:10.1109/MAHC.2014.50. ISSN 1058-6180. S2CID 16684090.
- ^ Wippermann, Hans-Wilm (1968) [1967-06-15, 1966]. "Definition von Schrankenzahlen in Triplex-ALGOL". Computing (in German). 3 (2). Karlsruhe, Germany: Springer: 99–109. doi:10.1007/BF02277452. ISSN 0010-485X. S2CID 36685400.
Further reading
[edit]- Randell, Brian & L. J. Russell (1964). ALGOL 60 Implementation: The Translation and Use of ALGOL 60 Programs on a Computer. Academic Press. CiteSeerX 10.1.1.737.475.. On the design of the Whetstone Compiler, and one of the early published descriptions of implementing a compiler.
- Dijkstra, E. W (1961). "ALGOL 60 Translation: An ALGOL 60 Translator for the X1 and Making a Translator for ALGOL 60" (PDF). report MR 35/61. Amsterdam: Mathematisch Centrum. Archived (PDF) from the original on 9 October 2022.
- Kruseman Aretz, Frans E.J. "The Dijkstra–Zonneveld ALGOL 60 Compiler for the Electrologica X1" (PDF). Historical note SEN, 2. Amsterdam: Centrum voor Wiskunde en Informatica. Archived (PDF) from the original on 9 October 2022.
External links
[edit]ALGOL
View on GrokipediaOverview
Definition and Origins
ALGOL, an acronym for Algorithmic Language, originated as the International Algebraic Language (IAL), a proposed standard for expressing algorithms in scientific computing. First outlined in a preliminary report published in 1958, it aimed to provide a machine-independent notation for describing computational processes, suitable for both publication and implementation on various computers.[3] The development began with preparatory efforts by the Association for Computing Machinery (ACM) in the United States and the Gesellschaft für Angewandte Mathematik und Mechanik (GAMM) in Europe. The pivotal joint ACM-GAMM conference held in Zurich, Switzerland, from May 27 to June 2, 1958, where the IAL was formally proposed. Key figures at the Zurich meeting included Friedrich L. Bauer, Hermann Bottenbruch, Heinz Rutishauser, and Klaus Samelson from GAMM, alongside John Backus, Charles Katz, Alan Perlis, and Joseph Wegstein from ACM; Peter Naur contributed to the broader ALGOL effort emerging from these foundations.[4][3][5] Unlike implementation-focused languages, ALGOL was designed primarily as a specification for algorithms, emphasizing clarity and portability over direct machine execution, with actual implementations varying across dialects and systems. Its initial goals centered on creating a universal language for scientific computing that balanced Fortran's practical efficiency with the elegance and precision of mathematical notation, thereby facilitating the exchange of programs and ideas among researchers worldwide.[3][5] This foundational work on IAL evolved into the more refined ALGOL 60 standard.Significance and Scope
ALGOL constitutes a family of imperative programming languages developed primarily for scientific and algorithmic purposes, encompassing major revisions such as ALGOL 58, ALGOL 60, and ALGOL 68, alongside minor variants including ALGOL W and ALGOL X.[5] These variants evolved through international collaboration, with ALGOL 58 serving as an initial proposal, ALGOL 60 establishing a widely referenced standard, ALGOL 68 introducing advanced features, and the W and X variants representing experimental extensions aimed at practical implementation and further refinement.[5] The family's scope emphasized machine-independent expression of algorithms, prioritizing clarity and generality over hardware-specific optimizations.[5] ALGOL's significance lies in its foundational contributions to structured programming, notably through the introduction of block structures for local scoping and recursion for procedural decomposition, concepts that became staples in subsequent language designs.[5] These innovations influenced a wide array of modern imperative languages, including Pascal, C, and Ada, by providing a formal framework for readable and modular code that bridged theoretical computer science with practical implementation.[6] Despite its limited direct use in production systems today, ALGOL remains a benchmark for language design due to its role in advancing syntax notation via Backus-Naur Form (BNF) and promoting portability as an ideal for algorithmic communication.[5] However, ALGOL's scope was deliberately narrow, focusing on abstract algorithmic description rather than input/output or hardware interfacing, which enhanced theoretical portability but resulted in implementation variances across systems and hindered widespread industrial adoption.[5] Adoption was notably stronger in Europe, where it was integrated into academic curricula and scientific computing, compared to the United States, where FORTRAN's established ecosystem prevailed.[5] Furthermore, ALGOL's design principles informed international standardization efforts, particularly through ISO's Working Group 2.1 on programming languages.[5]History
Early Development (ALGOL 58)
The development of ALGOL 58, originally proposed as the International Algebraic Language (IAL), began with a collaborative effort between the Association for Computing Machinery (ACM) in the United States and the Gesellschaft für Angewandte Mathematik und Mechanik (GAMM) in Europe. The pivotal event was the Zurich conference held from May 27 to June 2, 1958, at the Eidgenössische Technische Hochschule (ETH) in Zurich, Switzerland. This meeting brought together eight core delegates—four from each organization: Friedrich L. Bauer, Hermann Bottenbruch, Heinz Rutishauser, and Klaus Samelson from GAMM, and John W. Backus, Charles Katz, Alan J. Perlis, and Joseph H. Wegstein from ACM—along with additional contributors from both groups to draft a unified proposal for a standardized algorithmic language. The conference aimed to reconcile differing national approaches to programming languages, emphasizing clarity for mathematical expression, ease of mechanical translation to machine code, and suitability for publication of algorithms.[3] ALGOL 58 introduced several foundational innovations that influenced subsequent programming language design. Central to its structure was the concept of nested blocks, delimited bybegin and end keywords, which allowed for modular organization of code and lexical scoping of variables within inner blocks while inheriting from outer scopes. Procedures could declare own variables, which were local to the procedure and persisted across multiple calls, providing a mechanism for maintaining state without global pollution. Parameter passing employed call-by-name semantics, where formal parameters were textually substituted by actual arguments at the point of use, enabling flexible input/output behavior but introducing complexities in evaluation. These features marked a shift toward structured, block-based programming, distinguishing ALGOL 58 from earlier languages like Fortran.[3]
The preliminary report detailing ALGOL 58 was published in the January 1959 issue of Communications of the ACM, serving as the first formal specification of the language. The syntax adopted a pseudocode-like notation inspired by mathematical symbolism, using a "Reference Language" with basic symbols such as letters, digits, and delimiters (e.g., parentheses, commas) to define expressions, statements, and program units. Arithmetic and logical expressions followed conventional operator precedence, while control structures included assignment, conditional if statements, loops via for clauses, and jumps with go to. This design prioritized readability for human readers over strict machine syntax, facilitating the description of algorithms in scientific literature.[3]
Despite its advancements, ALGOL 58 faced significant challenges that highlighted its preliminary nature. Notably, the specification omitted any details on input/output operations, leaving I/O to be handled by external, machine-dependent procedures outside the core language. Additionally, the call-by-name parameter passing mechanism, while innovative, contained ambiguities regarding evaluation order and side effects, as the report described substitution without fully resolving potential inconsistencies in execution. These gaps, along with inconsistencies in syntax representation across implementations, underscored the need for revision, paving the way for the more refined ALGOL 60 standard.[3]
Standardization and Evolution (ALGOL 60)
The development of ALGOL 60 involved refining the preliminary ALGOL 58 report through a series of international meetings organized by the International Federation for Information Processing (IFIP) Working Group 2.1. Following preliminary discussions at the June 1959 International Conference on Information Processing (ICIP) in Paris, a pivotal conference was held in Paris from January 11 to 16, 1960, where delegates from Europe and the United States finalized the language specification. Peter Naur served as the rapporteur and editor, synthesizing contributions from 13 committee members, including John Backus and Friedrich L. Bauer, to produce a cohesive report. This document, titled "Report on the Algorithmic Language ALGOL 60," was published in Numerische Mathematik in 1960.[7] Key advancements in ALGOL 60 addressed limitations in the 1958 version by introducing a formal syntax definition using Backus-Naur Form (BNF), which provided a metalanguage for precisely describing the language's grammar and enabled unambiguous parsing. Arrays were enhanced to support dynamic bounds, allowing lower and upper limits to be specified as expressions evaluated at runtime rather than fixed constants, which improved flexibility for numerical computations. Input-output facilities were deliberately omitted from the core report due to implementation variances across systems; instead, they were standardized in a separate 1964 IFIP report proposing procedures like read and write.[7][8][9] ALGOL 60 rapidly gained traction as the de facto standard for algorithmic description in the 1960s, with more than 20 implementations by 1962 and dozens more by the mid-1960s. Notable early adoptions included the Elliott 803 compiler, developed by C.A.R. Hoare and colleagues in the UK, which demonstrated efficient block-structured execution on transistor-based hardware, and the Burroughs B5000 system in the US, designed from the outset to natively support ALGOL 60's stack-based semantics and recursion. Its influence extended to computer science education, becoming the primary language taught in European universities for programming and algorithm design, and it supported early computational research, including symbolic processing in nascent AI efforts.[10][11][12][13] A significant controversy during standardization centered on parameter-passing mechanisms, pitting call-by-value (evaluating arguments before substitution) against call-by-name (substituting and reevaluating expressions on each use). Proponents of call-by-value, including American delegates, argued for efficiency and predictability, while European advocates, such as Willem van der Poel, favored call-by-name for its mathematical expressiveness in simulating formal parameter substitution. The committee resolved the impasse by including both modes—defaulting to call-by-name for unspecified parameters—but this ambiguity led to implementation challenges and later critiques, as highlighted by Donald Knuth, who noted resultant semantic ambiguities in recursive and dynamic contexts.[14]Advanced Revisions (ALGOL 68)
The development of ALGOL 68 was led by the IFIP Working Group 2.1, beginning in 1962 as an effort to design a successor to ALGOL 60 under the working name ALGOL X.[15] After six years of meetings and deliberations marked by intense debates, a final draft report was completed and provisionally accepted in Munich, Germany, in December 1968, though it sparked significant controversy.[16] Internal conflicts, including resignations from key members and criticisms of the draft's readability and ambition, delayed formal endorsement and prompted the issuance of a minority report in March 1970, signed by figures such as Edsger W. Dijkstra, Tony Hoare, and Brian Randell, which described the project as a failed experiment due to its excessive complexity.[16][17] Further revisions were pursued through international meetings from 1970 to 1973, culminating in a revised report approved in Los Angeles in August 1973 and published in Acta Informatica in 1975.[18] ALGOL 68 pursued an orthogonal design philosophy, emphasizing a minimal set of primitive concepts that could be combined independently to maximize expressiveness while avoiding ad hoc rules.[19] A cornerstone innovation was its mode system, which enforced strong static typing through declarations of both primitive types (e.g., int, real, bool) and user-defined modes, supporting abstract data types via structures, unions, and recursive mode definitions like mu.[19][15] The language introduced primitives for parallel processing, including par clauses for concurrent execution of statements and semaphores (sema) for synchronization, allowing structured concurrency without reliance on low-level threading.[19] It also featured dynamic arrays via the flex keyword, enabling runtime-bound determination and resizing (e.g., flex [ ] real array), and provided a formal syntax via van Wijngaarden's two-level grammar, distinct from its operational semantics outlined in natural language.[19] Reception to ALGOL 68 was mixed, with praise for its technical depth overshadowed by widespread critiques of its complexity, particularly the esoteric grammar used in the report, which hindered comprehension and compiler development.[16] The 1970 minority report amplified these concerns, arguing that the language's bold innovations deviated too far from practical usability and recommending a more incremental approach instead.[17] Consequently, adoption remained limited despite its sophistication, with few complete implementations; prominent examples include the Algol 68-R subset for ICL 1900-series machines in the early 1970s and the full Algol 68-RS for the ICL 2900 series.[15][20]Post-ALGOL Developments
Following the release of the ALGOL 68 specification in 1968, several minor variants emerged as attempts to adapt the language for practical implementation amid hardware constraints and ongoing debates within the IFIP Working Group 2.1. One early offshoot was ALGOL W, developed in 1966 by Niklaus Wirth in collaboration with C. A. R. Hoare as a proposal for ALGOL X, the intended successor to ALGOL 60; it introduced features like the case statement and records while simplifying syntax for teaching and implementation.[21] ALGOL X itself remained unrealized as a full standard due to disagreements in the working group, but it directly influenced Wirth's later design of Pascal in 1970.[22] Another variant, ALGOL 68-R, appeared in 1970 as the first working compiler for ALGOL 68, implemented by the UK's Royal Radar Establishment on ICL 1900 series machines; it constituted a simplified subset, omitting advanced features like user-defined modes and certain transput capabilities to accommodate limited character sets and memory.[23][24] By the 1970s, ALGOL's influence waned as its complexity—particularly in ALGOL 68's orthogonal but intricate type system and syntax—hindered widespread adoption, leading to delays in implementations and a shift toward simpler alternatives.[22] Languages like Pascal, with its streamlined block structure and emphasis on readability, and C, optimized for systems programming on Unix, largely superseded ALGOL in academic and industrial use during this period. The last significant standardization effort was the Revised Report on ALGOL 68, published in March 1976 by the ALGOL 68 Support Subcommittee of IFIP WG 2.1, which incorporated errata up to 1978 and minor clarifications to syntax and semantics without major changes.[25] IFIP's active support for ALGOL effectively ended around 1980, as WG 2.1 shifted focus to newer algorithmic languages and calculi.[5] ALGOL 68 concepts, including its strong typing and parallel processing primitives, indirectly shaped later languages like Ada, where features such as environment inquiries and attributes drew from ALGOL 68's mode declarations. Into the 21st century, niche revivals have sustained limited interest; for instance, the ALGOL 68 Genie (68G) compiler-interpreter has seen ongoing maintenance for educational and historical purposes, while a GNU ALGOL 68 front-end for GCC continued development in 2025 despite not merging into the mainline release. Academically, ALGOL 68's type system has garnered renewed attention for verified programming, with tools developed in the 1970s to generate test cases for compiler verification highlighting its suitability for formal semantics and correctness proofs.[26][27]Design Principles
Syntax and Semantics
ALGOL's syntax was formally defined using Backus-Naur Form (BNF), a metalinguistic notation introduced by John Backus and Peter Naur in the 1962 Revised Report on ALGOL 60 to provide an unambiguous description of the language's structure.[28] BNF employs production rules that recursively specify how basic symbols—such as letters, digits, logical values, and delimiters—combine to form valid programs, enabling precise parsing independent of implementation details.[28] For instance, the syntax for expressions is defined as:<expression> ::= <arithmetic expression> | <Boolean expression> | <designational expression>
This rule illustrates how expressions encompass arithmetic, logical, and label-related constructs, with further productions detailing their components.[28] Similarly, statements follow hierarchical rules, such as the assignment statement:
<assignment statement> ::= <left part list> := <arithmetic expression>
These productions emphasize ALGOL's hierarchical composition, where non-terminals (enclosed in angle brackets) expand into sequences or alternatives, facilitating lexical analysis by breaking programs into tokens like identifiers and operators.[28]
Semantically, ALGOL prioritizes static (lexical) scoping, where the visibility of identifiers is determined by their textual position in the program structure, ensuring that local declarations within a block obscure outer ones without runtime resolution.[28] This approach aligns the program's static form with its execution behavior, promoting predictability in nested blocks.[28] In ALGOL 68, semantics are elaborated through a two-level grammar that defines meaning via "elaboration" of production trees in an environment, yielding values and actions such as name creation and dereferencing, which formalizes program execution in a manner akin to denotational semantics.[25] Lexical analysis in both versions processes input into basic symbols and tokens, with ALGOL 68 extending this to handle pragments (ignored annotations) and structured formats, ensuring syntax remains context-free where possible.[25]
ALGOL was conceived as a machine-independent metalanguage for describing algorithms, focusing on computational processes through expressions and statements rather than hardware specifics, allowing portability across systems by abstracting numerical and logical operations.[28] This principle evolved in ALGOL 68, where implementations could adapt to varying character sets and hardware without altering core semantics, using abstract data types and coercion rules to maintain consistency.[25] Unique syntactic elements, drawn from mathematical notation, include := for assignment to distinguish it from equality testing, and → for logical implication in Boolean expressions, enhancing readability for algorithmic intent.[28] These features underscore ALGOL's role in formalizing unambiguous, portable algorithmic description.[25]
Block Structure and Scope
ALGOL introduced the concept of block structure in its 1958 specification, usingbegin and end delimiters to enclose sequences of declarations and statements, thereby creating local scopes for variables and limiting their visibility to within the block.[3] This allowed programmers to organize code modularly, with declarations inside a block applying only to that enclosed region, independent of outer contexts. Labeled blocks further enabled targeted control flow while maintaining scope isolation.[3]
The ALGOL 60 revised report refined this foundation by formalizing blocks as sequences of declarations followed by statements within begin and end, introducing compound statements for nesting and lexical (static) scoping rules.[28] Under lexical scoping, a variable's visibility extends from its declaration point to the end of the block, with nested blocks inheriting outer scopes unless redeclared locally; this ensured predictable binding based on program text structure rather than runtime call sequences.[28] To support persistent storage across recursive or repeated procedure calls, ALGOL 60 added the own declarator for variables, allocating them statically so their values remain unchanged upon re-entry to the block.[28] However, the call-by-name parameter mechanism introduced dynamic binding elements, where actual parameters were textually substituted at call sites, potentially resolving free variables in the caller's dynamic environment.[29]
ALGOL 68 evolved these mechanics by unifying blocks with serial clauses and introducing dynamic scope concepts through environs and locales, allowing scopes to be managed relative to runtime creation contexts.[19] Deproceduring, a coercion that treats routines as manipulable values, enabled flexible dynamic scope interactions, such as assigning jumps to variables or customizing event handlers with scopes tied to their invocation environ.[19] While retaining lexical scoping for compile-time checks in most cases, these additions supported heap-based dynamic allocation and nonlocal clauses for precise scope resolution, addressing limitations in earlier versions for more complex, runtime-adaptive programs.[19]
This block-structured approach profoundly influenced programming practices by encouraging modular organization and reducing dependence on unstructured goto statements, as nested scopes facilitated clear control flow and readability without arbitrary jumps.[30] Edsger W. Dijkstra highlighted ALGOL's block structure as a key innovation enabling disciplined, hierarchical code, paving the way for structured programming paradigms in subsequent languages.[31]
Type System and Expressions
ALGOL 60 introduced a simple yet strict type system centered on three basic types: integer for whole numbers, real for floating-point numbers, and Boolean for logical values true or false.[28] These types denote fundamental properties of values, with no support for strings or characters as built-in types; labels and strings were handled separately without formal typing.[28] Variable declarations required explicit specification of the type, using syntax such asinteger array_name; or real variable_name;, ensuring all variables were typed at declaration within a block.[28] Arrays were declared with explicit bounds, as in integer array a[1:10];, supporting multidimensional structures but with fixed bounds determined at compile time.[28]
Expressions in ALGOL 60 were categorized into arithmetic, Boolean (logical), and designational types, evaluated strictly according to their type without implicit conversions between them.[28] Arithmetic expressions used operators like +, -, ×, /, and ↑ (exponentiation), with precedence rules applying left-to-right evaluation: exponentiation first, followed by multiplication and division, then addition and subtraction, overridden by parentheses.[28] For example, in a + b × c ↑ 2, the expression evaluates as a + (b × (c ↑ 2)). Logical expressions employed operators such as ¬ (negation), ∧ (and), ∨ (or), ⇒ (implication), and ≡ (equivalence), with precedence ordering relations highest, then negation, conjunction, disjunction, implication, and equivalence last.[28] Conditional expressions followed the form if ([Boolean](/page/Boolean)_expression) then (expression) else (expression), allowing type-consistent branching where the then and else parts must match the overall expression type.[28] Type mismatches, such as assigning a Boolean to an integer variable, resulted in compilation errors, enforcing strong typing without any automatic coercions.[32]
ALGOL 68 expanded the type system significantly by introducing "modes" as a more flexible and composable alternative to ALGOL 60's basic types, incorporating the originals (renamed int, real, bool) alongside additions like char, void, bits, bytes, and string.[25] User-defined modes could be created via declarations like mode new_mode = existing_mode;, enabling structured types such as struct for records (e.g., mode complex = struct(real re, im);) and union for variant types (e.g., union(int, real);).[25] Reference types (ref mode) allowed pointer-like access, declared as ref int x;, supporting dynamic memory management.[25] Declarations remained explicit, using forms like int x = 5; or ref real y becomes new_value;, with variables bound to modes at declaration and visible within their scope.[25]
Array modes in ALGOL 68 supported dynamic bounds through flex declarations, such as flex [ ] real [array](/page/Array); or flex [1:n] int matrix;, where bounds could be runtime-evaluated.[25] Slicing enabled extraction of subarrays, as in matrix[2:5], yielding a new array with adjusted bounds inclusive of the specified indices.[25] Expressions built on operator declarations with customizable priorities, covering arithmetic (+, -, *, /), logical (and, or, not), and relational operators (=, <, >), evaluated left-to-right with monadic operators taking precedence over dyadic ones.[25] Priorities were specified via prio declarations, such as prio + = 7;, allowing user-defined precedence. Short-circuit evaluation applied to logical operators like and and or, where evaluation proceeded left-to-right and halted once the outcome was determined (e.g., skipping the second operand in false and expression).[25] While ALGOL 68 permitted limited coercions for widening (e.g., int to real), it enforced strict mode checking, flagging incompatible operations as errors to maintain type safety.[25]
Key Features
Control Structures
ALGOL introduced structured control mechanisms to promote readable and maintainable code, emphasizing alternatives to unstructured branching. In ALGOL 60, the primary conditional construct is the if-statement, which evaluates a Boolean expression to select between execution paths. The syntax isif boolean-expression then statement [else statement], where the optional else clause executes if the condition is false.[28] The language resolves the dangling else ambiguity by associating the else with the nearest unmatched if, ensuring unambiguous parsing without additional keywords.[28]
Loops in ALGOL 60 center on the for-statement, designed for iterating over arithmetic progressions with flexible clauses. The full syntax is for variable := [list of clauses] do statement, where clauses include initial value (initial value), step increment (step increment until upper limit), and conditional termination (while boolean-expression). For example:
for i := 1 step 2 until 10 do
sum := sum + i
This iterates i from 1 to 10 in steps of 2, adding each value to sum, and halts early if the while condition fails.[28] ALGOL 60 also supports a while-do form implicitly within the for-loop, but lacks a standalone repeat-until; variants in implementations sometimes added such constructs for backward compatibility.[28]
For multi-way selection, ALGOL 60 includes the switch-statement, which dispatches to a designational expression based on an integer subscript. The syntax is switch identifier := designator1, designator2, ..., designatorn, where the subscript selects the corresponding label. For instance:
switch S := L1, L2, if x > 0 then L3 else L4
Here, S=1 jumps to L1, S=2 to L2, and S=3 to L3 or L4 based on x.[28] Although ALGOL discouraged unstructured control, it retained the go to statement for transfers to labels, as in go to label, with warnings about its potential to complicate program flow.[28]
ALGOL 68 evolved these structures for greater expressiveness and orthogonality. The if-statement extended to if boolean then clause [else clause] fi, mandating fi for closure and allowing the structure to yield values.[33] It introduced the case-of construct for mode-based selection, as in case united-value in (mode1 var1): clause1, (mode2 var2): clause2 out default-clause esac, enabling discriminated unions to route to appropriate handlers.[33] Loops advanced with a refined for-loop: for identifier from low by step to high [while condition] do clause od, incorporating optional while for early exit.[33] ALGOL 68 added explicit while-do as while boolean do clause od and supported repeat-like behavior through guarded loops, while retaining go to but de-emphasizing it.[33] A novel addition was concurrent clauses via par clause1, clause2 par, allowing parallel execution of independent units, synchronized implicitly or via semaphores.[33]
Procedures and Recursion
ALGOL introduced procedures as a mechanism for defining reusable blocks of code, declared using theprocedure keyword followed by an identifier, formal parameters, and a body enclosed in begin and end.[34] In ALGOL 60, a procedure declaration specifies the types of formal parameters and any result type, with the body forming a block that introduces local scope.[35] Procedures served both as subroutines for actions and as functions for computations, without a distinction between the two; values were returned by assigning to the procedure identifier itself if it had a type declarator.[34]
Parameter passing in ALGOL 60 supported two modes: call-by-value and call-by-name.[34] In call-by-value, specified with the value keyword, the actual parameter's value is copied to the formal parameter at call time, ensuring independence from subsequent changes to the actual.[35] Call-by-name, the default, treated the actual parameter as a textual substitute for the formal one, re-evaluating it each time the formal is referenced in the body, akin to macro expansion but with dynamic scoping implications.[34] This mechanism enabled powerful but controversial idioms, such as Jensen's device, where a procedure iterates over an expression like a summation, re-evaluating it per iteration to access array elements indirectly.[36] Implementations often used stack-based thunks to simulate call-by-name efficiently, though it posed challenges for optimization due to potential multiple evaluations.[37]
ALGOL 68 refined parameter passing by introducing call-by-reference using the ref mode for formal parameters (e.g., ref int y), allowing direct modification of the actual parameter, in addition to call-by-value (e.g., int x).[33][38] This enhanced efficiency for structured types. Procedure declarations in ALGOL 68 used proc for the mode, allowing routines as first-class values storable in variables or passed as parameters, a departure from ALGOL 60's static treatment.[33]
Recursion was fully supported in ALGOL 60 through procedure activation records on the call stack, allowing a procedure to invoke itself directly or indirectly without special syntax.[34] This feature, added late in the design process under mathematical influences like LISP, enabled elegant solutions to problems such as tree traversals or the greatest common divisor, with the semantics ensuring proper scope via block nesting.[39] ALGOL 68 preserved and extended this with explicit recursive mode declarations, verifying well-formedness to prevent circular definitions, and supporting recursive calls in heap-allocated contexts for deeper nesting.[33]
The following example illustrates a recursive procedure in ALGOL 60 for factorial computation:
integer procedure fact(n); value n; integer n;
fact := if n <= 1 then 1 else n * fact(n-1);
Here, fact calls itself until the base case, returning the product via assignment to its own identifier.[35] In ALGOL 68, an equivalent might use proc with a result mode:
proc fact = (int n) int:
if n <= 1 then 1
else n * fact(n-1);
This highlights the modular, recursive nature central to ALGOL's influence on structured programming.[33]
Input-Output and Portability
ALGOL 60's core specification deliberately excluded input-output operations to maintain machine independence, as these were considered too hardware-dependent for standardization. Instead, a separate proposal by the ACM ALGOL committee introduced conventions using procedures such asget for input and put for output, emphasizing format-free transput to allow flexible, machine-agnostic data exchange without predefined formatting constraints.[40] This approach enabled implementations to adapt I/O to local devices while preserving algorithmic intent.[41]
In ALGOL 68, input-output evolved into a more comprehensive "transput" system integrated via declarations, supporting structured handling through hierarchical components like books (for text storage), channels (for stream interfaces), and files (for program-media links). Key procedures such as read, print, putf (formatted output), and getf (formatted input) allowed for formatless, formatted, and binary transput, with event routines for error handling and mode compatibility to enhance robustness.[25] This design addressed ALGOL 60's limitations by providing runtime data transfer mechanisms compatible with external media, while maintaining orthogonality with the language's type system.[25]
ALGOL was engineered for portability, prioritizing machine independence through abstract specifications that avoided hardware-specific details, particularly in areas like I/O where vagueness permitted implementation flexibility. The language's reference form defined a universal syntax, with hardware representations transliterating symbols to local character sets, aiming to facilitate program interchange across systems.[34] However, differing I/O devices and character encodings in the 1960s era complicated this goal, as no universal set like ASCII existed initially.[42]
Character set limitations further impacted portability; while ALGOL 60's reference language used a defined alphabet of letters, digits, and delimiters, implementations often restricted to 7-bit ASCII subsets, leading to variances in symbol representation and non-portable code when programs relied on specific notations.[34] These discrepancies, combined with optional I/O extensions, resulted in implementation-specific behaviors that hindered direct code transfer between compilers.[42]
The evolution of special characters in ALGOL specifications reflected adaptations to mathematical notation and hardware constraints, starting with ALGOL 58's use of symbols like ÷ (division) and ↑ (exponentiation) in its 63-character set for algorithmic clarity. ALGOL 60 retained similar symbols in its reference language, such as ↑ for power and ÷ for real division, while introducing hardware mappings to accommodate limited keyboards. ALGOL 68 expanded this with metasyntactic notation, employing ß (bold standard) and ℵ (parallel clause) to denote grammatical constructs in its two-level grammar.[3][34][25]
| Version | Symbol | Meaning/Use |
|---|---|---|
| ALGOL 58 | ÷ | Real division operator |
| ALGOL 58 | ↑ | Exponentiation operator |
| ALGOL 60 | ÷ | Real division (reference language) |
| ALGOL 60 | ↑ | Exponentiation (reference language) |
| ALGOL 60 | := | Assignment (introduced for clarity) |
| ALGOL 68 | ß | Boldface for standard modes in metalinguistics |
| ALGOL 68 | ℵ | Parallel clause delimiter in grammar |
Implementations
Major Compilers and Systems
One of the earliest prominent implementations of ALGOL 60 was ELLIOTT ALGOL, developed in the United Kingdom during the 1960s for the Elliott 803 computer.[43] This compiler provided an almost complete realization of the ALGOL 60 specification, with minor limitations in areas such as dynamic array bounds and certain own variables, tailored to the hardware constraints of the Elliott systems.[43] It was designed by C.A.R. Hoare and became influential in British computing environments, supporting efficient compilation on early transistor-based machines.[11] The Burroughs B5000, introduced in 1961, featured a native ALGOL 60 compiler optimized for its stack-based architecture, which used tagged memory and hardware support for recursion and block structure.[44] This implementation, often extended as Extended ALGOL, leveraged the machine's single-pass compilation and integrated the language deeply into the system's Master Control Program (MCP) operating system, enabling direct execution of ALGOL code without intermediate assembly.[45] The stack-oriented design facilitated efficient handling of procedure calls and expressions, making it one of the first hardware-software systems explicitly built around ALGOL 60 principles.[46] For the CDC 6600 supercomputer, released in 1964, an ALGOL 60 compiler was developed as part of the CDC 6000 series tools, based on designs from Regnecentralen in Denmark.[47] This implementation supported the full core language on the high-performance vector-processing hardware, with optimizations for scientific computing workloads, though it required adaptations for the machine's 60-bit word architecture.[48] It was assessed in comparative studies as one of the more complete ALGOL 60 compilers of the era, handling control structures and recursion effectively despite the era's limited resources. Turning to ALGOL 68, the Algol 68C compiler, originating from Cambridge University in the mid-1970s, was a portable subset implementation that restricted advanced features like user-defined operators and omitted automatic garbage collection to ensure broader compatibility.[20] Developed by Stephen Bourne and Michael Guy, it targeted multiple platforms including IBM and DEC systems, emphasizing ease of porting while maintaining core orthogonality.[20] This made it suitable for academic and research use, with detailed implementors' guides aiding further adaptations.[20] Portable implementations of ALGOL 68 also emerged from Oxford, notably through efforts by Oxford and Cambridge Compilers Limited, which produced the Interactive ALGOL 68 system in the 1980s but rooted in 1970s research.[20] This compiler focused on full-language support with interactive features, running on systems like the ICL 2900 series and providing source code availability for customization.[20] It highlighted the language's portability goals, allowing deployment across diverse hardware without major rewrites.[20] ALGOL variants integrated with operating systems included support on Multics, where ALGOL 68 was one of the hosted languages alongside PL/I, enabling seamless inter-language calls in the time-sharing environment.[49] Academic efforts produced compilers like Stanford's ALGOL W, a simplified ALGOL 60 derivative implemented on IBM 360 systems in the late 1960s and revised through the 1970s.[50] This compiler added features such as string handling and call-by-result while retaining block structure, and it was widely used for teaching and research at Stanford.[50] By 1970, ALGOL 60 alone had spurred dozens of implementations across Europe and the US, leading to a fragmented ecosystem of dialects adapted to specific machines, though exact counts varied due to incomplete surveys. This proliferation, while demonstrating the language's influence, complicated standardization efforts.[51] As of 2025, active open-source implementations persist, including ports of ALGOL 68RS such as algol68toc, which translates ALGOL 68 to C and runs on modern platforms like Linux and Windows.[52] Ongoing work, including GCC front-end support for ALGOL 68, keeps these systems viable for legacy code maintenance and experimentation.[53]Challenges and Adaptations
One of the primary challenges in implementing ALGOL 60 stemmed from its call-by-name parameter passing mechanism, which required compilers to generate "thunks"—small inline functions that reevaluated the actual parameter expression each time the formal parameter was referenced within the procedure body. This approach, while semantically precise, introduced substantial runtime overhead, particularly for expressions involving side effects or complex computations, as the thunk could be invoked multiple times per procedure call, exacerbating execution time on resource-constrained hardware of the era.[10][14] Donald Knuth highlighted this inefficiency, noting that call-by-name often led to unintended recomputations and difficulties in optimization, making it a frequent point of criticism in early compiler designs.[14] ALGOL 60's memory management further compounded implementation difficulties, as the language lacked built-in garbage collection and relied on manual allocation for dynamic structures like variable-bound arrays in "own" storage classes. Programmers and implementers had to explicitly manage deallocation to avoid leaks or overflows, but the block-structured scope rules complicated this, especially for recursive procedures where storage lifetimes intertwined with call stacks. The allocation of storage for such dynamic arrays posed particular challenges, requiring compilers to handle runtime dimensioning without predefined heap mechanisms, often resulting in fragmented memory usage or the need for custom runtime support. To address these issues, many implementations adopted subsets of ALGOL 60, such as those outlined in the Modified Report, which relaxed features like full call-by-name or dynamic array bounds to simplify compilation and improve performance on limited hardware. For instance, ALGOL 60 Modified permitted implementers to omit or restrict problematic elements, enabling portable code across diverse systems while maintaining core syntactic integrity. Later, ALGOL 68 saw adaptations for real-time applications.[54][55] Efficiency concerns with recursion were acute on early machines with small memory footprints, where deep call stacks could quickly exhaust available storage, leading to runtime errors in programs like tree traversals or iterative solvers. Compilers for systems like the DECSystem 10 addressed this by allowing manual stack simulation via arrays, effectively bypassing recursion limits, while some incorporated tail-call optimization to reuse stack frames in linear recursive patterns, reducing depth without altering semantics. Debugging tools for ALGOL were notably scarce in the 1960s, with most environments relying on rudimentary print statements or post-mortem dumps due to the complexity of tracing thunks and dynamic scopes, which hindered development of non-trivial programs. Portability efforts, as discussed in early implementation surveys, revealed inconsistencies in subset adherence and I/O handling, prompting recommendations from working groups to standardize minimal viable features for cross-machine compatibility.[10]Examples
Basic Code Samples
ALGOL 60 introduced structured programming concepts through its block structure and control flow mechanisms, as exemplified in a simple program that computes the sum of squares from 1 to n using a for-loop and a procedure. The following code sample, adapted from the language's syntax for summation tasks, declares variables within a block, initializes a sum, iterates using a for-loop, and invokes a procedure to encapsulate the computation.[56]begin
integer n, i, sum;
procedure squaresum(k); value k; integer k, i, squaresum;
begin
integer s;
s := 0;
for i := 1 step 1 until k do
s := s + i * i;
squaresum := s
end squaresum;
n := 10;
sum := squaresum(n);
comment Output sum; % Implementation-specific I/O, e.g., outinteger(1, sum);
end
This program begins with the begin keyword to open the main block, declaring n, i, and sum as integers. The procedure squaresum is defined with value k for pass-by-value, taking an integer k and returning the sum of squares up to k; it declares a local s, initializes it to 0, and uses a for-loop where i starts at 1, steps by 1, until k, accumulating i * i into s via assignment with :=. The main block sets n to 10, calls the procedure to compute the sum (yielding 385 for n=10), and assigns it to sum. Input/output is not part of the core ALGOL 60 specification and relies on implementation extensions like outinteger.[56][57]
ALGOL 68 extended type systems with user-defined modes and flexible array handling, allowing declarations of composite types and dynamic bounds. The sample below declares modes for one- and two-dimensional arrays and manipulates a one-dimensional array to compute an inner product, demonstrating mode declarations, array slicing, and looping.[25]
mode realvec(n) = [1:n] real; # Parameterized mode for 1D real array #
mode matrix(m, n) = [1:m, 1:n] real; # Parameterized mode for 2D real matrix #
begin
int n = 5;
realvec(n) a, b;
real sum := 0;
a := (1,2,3,4,5);
b := (1,1,1,1,1);
for i to n do
sum +:= a[i] * b[i]
od;
# Output sum; e.g., print((sum)); % Yields 15 #
comment For 2D example: matrix(2, 2) mat = [[1,2],[3,4]]; real elem = mat[1,2]; # Accesses 2 #
end
The code opens with parameterized mode declarations: realvec(n) as a bounded array [1:n] real and matrix(m, n) as [1:m, 1:n] real, enabling reusable type definitions for arrays with specified dimensions. The main block declares n as 5, a and b as realvec(5) (conforming to the mode), and initializes sum to 0; it then assigns tuples to a and b. A for-loop iterates i from 1 to n, adding the product a[i] * b[i] to sum using the +:= operator for accumulation. The comment illustrates 2D access via matrix(2, 2) mode, subscripting with [row, col]. Output uses implementation-specific print. ALGOL 68 employs special symbols like ⩤ for unions in mode definitions, though not used here, to denote type alternatives such as union (real, int).[25]
Comparative Portability Timeline
The evolution of ALGOL's syntax for basic output operations illustrates its growing standardization and the persistent portability challenges across versions. In ALGOL 58, also known as the International Algebraic Language (IAL), output was described in pseudocode rather than executable syntax, with no built-in mechanisms; simple printing was implied through external procedures likeprint(value), as seen in numerical examples such as the Simpson's rule integration procedure, where results are returned but not directly outputted.[3] This descriptive approach prioritized algorithmic clarity over implementation details. By ALGOL 60, the Revised Report still omitted standardized input/output in the core language to maintain machine independence, leaving it to implementations; a common "Hello, World!" equivalent relied on vendor-specific routines, such as 'outstring'(1, "Hello, World!") in some systems, often wrapped in a loop for repetition.[58] ALGOL 68 addressed this vagueness by introducing formalized transput (input/output) in its standard prelude, using the print procedure for output; a basic example is print(("Hello, World!", newline)), which outputs the string followed by a line break to the standard output channel.[25]
These syntactic shifts highlight portability hurdles, as code written for one version or implementation often required adaptation. For instance, parameter passing mechanisms differed significantly, affecting procedure calls and data handling. The table below compares simple examples of value and non-value passing in ALGOL 60 versus ALGOL 68.
| Aspect | ALGOL 60 Example (Call-by-Value and Call-by-Name) | ALGOL 68 Example (Call-by-Value and Call-by-Reference) |
|---|---|---|
| Declaration | procedure double(value x); real x; begin x := 2 * x; end procedure sum(s, i; value k, n); real s; integer i, k, n; begin ... s := s + a[i]; ... end (s and i by name) | proc double(val int x) void: x := 2 * x proc sum(ref real s, ref int i; val int k, n) void: ... s +:= a[i]; ... end (united mode with ref for reference) |
| Call | double(5); (value passes copy) integer idx := 1; sum(total, idx, 1, 10); (name re-evaluates idx each time, potentially modifying caller) | double(y); (value passes copy, y unchanged) int z := 5; sum(total, z, 1, 10); (reference modifies z directly) |
| Behavior | Call-by-name can lead to unexpected re-evaluations, like in Jensen's device for array summation. | Reference provides direct aliasing, avoiding textual substitution issues but requiring explicit val/ref modes. |
| Aspect | ALGOL 60 (No Standard I/O) | ALGOL 68 (Standard Transput) |
|---|---|---|
| Output Syntax | Implementation-dependent; e.g., 'outreal'(1, 3.14) or library print("text") | print(("text", [newline](/page/Newline))) or put(stand out, value) |
| Input Syntax | Similar, e.g., 'inreal'(1, x) | read((x)) or get(stand in, value) |
| Formatting | None in core; ad hoc via procedures | Built-in with pictures, e.g., putf(output, ($g(0,2)$)) for decimals |
| Portability Note | Varied by compiler (e.g., Burroughs vs. IBM); required rewrites for strings/numerics | Standardized but implementation-specific channels; still needed adaptation for devices |
real array a[-5:10], but defaults to 1 if unspecified, and implementations varied in bound evaluation (static vs. dynamic).[58] ALGOL 68 extended this with mode-based flexibility, supporting arbitrary bounds and slicing (e.g., real a = [-1:1] real), but differing runtime checks across compilers affected portability.[25] Character encoding posed another barrier: ALGOL 60 implementations used diverse sets (e.g., 6-bit Hollerith on IBM, ASCII on others), causing string literals and output mismatches, such as non-printable characters or encoding shifts in transatlantic ports.[59] These variances—coupled with I/O and parameter differences—meant ALGOL programs frequently required significant refactoring for cross-system execution, undermining its goal of universal portability despite formal syntax definitions.[15]