Algol 68 is a language in the Algol family of languages. As a descendent of Algol 60, it influenced later languages such as Algol W, Pascal, O'CAML and Scheme, making it a strong influence in computer science in general and programming language design in particular. Despite its influence, the language was never popular. One reason for this was, due to the complexities inherent in the language design, compilers were hard to write.
Algol 68 shares a few significant features with its predecessor, Algol 60, but deviates in other areas. The discussion of this paper is to discuss the significant features of Algol 68, and, if necessary, highlight implications in these design decisions.
Algol 68 is known as a highly orthogonal language. The intention of the language designers was to create a small language that did not have any artificial limitations on how the elements of the languages are used in expressing code. Algol 68's orthogonality can create some interesting combinations in terms of what can be expressed, but the amount of orthogonality present in Algol 68 can make for more complicated grammar descriptions of the language.
Here are examples of the orthogonality in Algol 68:
3 * (a := c + 4) + 2 ;
X := IF a < 2 THEN 3.2 ELSE 5.2 FI ;
IF a < 2 x THEN y FI := 3.5 ;
One can execute a print statement as such:
print(IF a < 2 THEN
"a is less than two"
ELSE-IF a = 2 THEN
"a equals two"
"a is greater than two"
A statement like:
REF INT size = LOC INT; read(size);
REFINT a = LOC[1:size]INT
can be turned into:
REFINT r = LOC[1:(REF INT i=LOC INT; read(i); i)]INT
Both code samples define a dynamically sized array given user input.
Algol 68 can be a very readable language, but due to its extreme orthogonality, the language can allow rather obtuse looking statements which, in turn can be hard to read.
Algol 68 uses the term "modes" for data types. The standard modes are integers, real numbers, characters, and strings, which are defined as character arrays. Users can extend the mode system with new modes, with structures and unions. Here is an example mode:
MODE Point = STRUCT (INT x, INT y)
Point t := (1,2)
print(x IN t)
print(y IN t)
Algol 68 has built-in support for arrays, (which is sometimes referred to as "multiples"). Arrays can be declared dynamically. In Algol 68, these are called “flex” arrays, which can dynamically change size on assignment. An example of a flex array is below:
The array is allocated with no space for integers, but is automatically sized on assignment.
Arrays have a powerful slicing feature. Taking a slice out of an array involves specifying a range of indexes to create a new array.
N-dimensional arrays are supported as well. An n-dimensional array can be sliced by row or by column, or a combination of both.
Algol 68's ability of abstraction is represented in procedures. A procedure can take zero or more parameters and must return an existing type. Here is an example of an Algol 68 procedure definition, which also demonstrates Algol 68's recursive capabilities:
PROC factorial = (INT x)INT:
(x = 1 || x = 0|x|x * factorial(x-1))
The last statement executed in a procedure is the value that is returned. In this case, at the completion of this procedure, "x * factorial(x-1)" will be returned.
Procedures also act like variables, so the procedure can be passed as a value into another procedure. Here is a procedure, "map and print", which takes an array of integers and applies a procedure to each value:
PROC map and print = (INT x, PROC (INT)INT procs)VOID:
FOR i FROM LWB x TO UPB x DO
INT vals = [5, 4, 2, 4];
map and print(vals, factorial)
(As a side note, variable and procedure identifiers can have spaces in them, unlike in other languages.)
Along with procedures, new operators can be defined. An operator in Algol 68 is either monadic or dyadic (one operand or two operands). Operators are distinct from procedures in that they have priorities. An existing operator, such as the arithmetic operators can be used, for existing and user-defined modes. An example of this concept is specifying an integer in an add operation to increment a pointer in a linked list:
MODE REF Node;
MODE List = STRUCT (List next, INT info);
PRIO GOUPTO = 1
OP GOUPTO = (REF List k, INT i)VOID:
FOR j FROM 1 TO i DO
t := next IN k;
k := t;
t GOUPTO 3
In the above example, the priority of the GOUPTO operator is set to 1. An operator can have its priority set from 1 to 9. This feature complicates compiler development. When the priority of operators is modified, the compiler must recognize the priority and execute (or write appropriate machine-level code) that reflects the new operator precedence.
Both procedures and operators support call-by-reference semantics as well as call-by-value semantics (as demonstrated in the above operator definition.)
Algol 68 specifies an I/O library called "transput". Transput is defined by "channels" to and from "books". Essentially put, "books" are operating system files and "channels" are streams of data from the program to the book and vice versa.
Algol 68, despite suffering in popularity, was instrumental in influencing later programming languages. It is a highly expressive language, given its orthogonal nature. It's expressiveness was something that was far beyond its contemporaries, which combined simplicity and flexibility to create a useful language for scientific programming.
(Procedural support, Operator Overloading, Orthogonality In Terms Of Data Types)