ALGOL 60 and the Revised Report

As mentioned in the previous post, ALGOL was designed by an international committee of computer scientists: their goal was to create a universal language for expressing algorithms without recourse to hardware specific features.

The result of their discussions was the ALGOL 60 Report, with a slightly corrected version known as the Revised Report released a few years later. This was one of the first attempts to formally specify a language, using Backus-Naur form (JW Backus and Peter Naur were both on the ALGOL committee).

Representations

ALGOL was intended as a universal language, but at the time of its creation there was no universal character set such as Unicode or even ASCII; as a result, the report defines three representations of the language:

  • A reference language used by the committee in the report to describe ALGOL
  • Publication language, which modifies the reference language for use in handwritten or published documents
  • Hardware representations, which modifies the reference language based on the character set of the hardware it is running on.

An example is the exponentiation operator.

  • In the reference language the upwards facing arrow ↑ is used, eg a ↑ b.
  • In the publication language, superscript is used for the exponent, eg ab.
  • In the hardware representation used by IBM, 'POWER' or ** is used, eg a ** b.

One of the most important differences in representation were basic symbols like begin or end. In the reference and publication language these were usually underlines, eg begin. In many hardware representations, including IBM's, they were enclosed in quotes eg 'BEGIN',

A summary of the differences between the reference language and the IBM hardware representation is shown below; in some cases there is more than once choice for the hardware representation.

Reference   Hardware       Hardware alt  
×           * 
↑           'POWER'        **
÷           '/'
>           'GREATER'      >
<           'LESS'         <  
≤           'NOTGREATER'   <=
≥           'NOTLESS'      >=
≠           'NOT EQUAL'    ¬=
≡           'EQUIV'
⊃           'IMPL'
∧           'AND'          &
∨           'OR'           |
¬           'NOT'
:            :             ..
;            ;             .,
₁₀          '
[           (/
]           /)
‘           '('
’           ')'

The "₁₀" is a scale factor like "E" in the C language, eg 1234 could be expressed as "1.234₁₀3";

In the rest of this post, I will use the reference language in the body text and the IBM hardware representation in the monospaced examples.

Blocks and statements

ALGOL 60 is free format, with statements separated by semicolons. It is possible to group statements into a block, marked by begin and end and optionally labeled. Comments are started with the keyword comment and ended with a ;; this is not needed at the end of blocks.

'COMMENT' Block example;  
'BEGIN'  
    X: 'BEGIN'
        FN1(10);
        FN1(20);
    'END' this is the end of the X block
'END' and this the unnamed block  

Types and variables

ALGOL 60 supports integer, real and Boolean types and variables. There is no restriction in the standard on variable name length, but *ALGOL limits them to six characters. All variables must be declared with their types and variable lifetime is the block. The standard does define a storage class called own, similar to C's static, but this is not supported by the IBM compiler.

The below will print "3 4 3":

'BEGIN'  
    'INTEGER' I, J;
    I := 3;
    OUTINTEGER(1, I);
    'BEGIN'
        'INTEGER' I;
        'BOOLEAN' STATE;
        I := 4;
        OUTINTEGER(1, I);
    'END'
    OUTINTEGER(1, I);
'END'  

Multi-dimensional arrays can be declared, with variable bounds:

'INTEGER' 'ARRAY' A(/-1:+1, M:N/);  
A(/0,15/) := 42;

Strings are supported only as constant parameters to function; it is not possible to declare string variables.

OUTSTRING(1, '('This is a string')');  

Expressions

The usual arithmetic expressions are available; it's possible to include an if/else in such expressions. Unusually, Boolean expressions include operators for implies and equivalent.

'BEGIN'  
    'INTEGER' X, Y;
    'BOOLEAN' A, B;
    X := 3;
    Y := 4;
    A := 'TRUE';
    B := 'FALSE';
    OUTINTEGER(1, X + Y - ('IF' A 'OR' B 'THEN' 1 'ELSE' 2));
'END'  

The above will print 6.

Control statements

As well as the regular goto statement, the switch statement allow selection of a statement label to jump to.

if ... then ... else can be used for conditional execution. Another if cannot follow the then unless it is contained in a block. to prevent ambiguity of which if then else is attached to.

The for statement is used for repetition: there are three forms:

'BEGIN'  
    'INTEGER' J;
    'FOR' J := 1, 2, 3 'DO' OUTINTEGER(1, J);
    'FOR' J := 10 'STEP' 5 'UNTIL' 20 'DO' OUTINTEGER(1, J);
    'FOR' J := 100, J*2 'WHILE' J 'LESS' 500 'DO' OUTINTEGER(1, J);
'END'  

This will print

  • 1, 2, 3
  • 10, 15, 20
  • 100, 200, 400

Procedures

Procedures support pass by value or pass by name parameters. Pass by value is familiar: a copy is made of the parameter for those identified with value in the procedure preamble. The following will print 42:

'BEGIN'  
    'INTEGER' 'PROCEDURE' ADD2(X, Y);
    'VALUE' X, Y;
    'INTEGER' X, Y;
    'BEGIN'
        ADD2 := X + Y;
    'END'

    OUTINTEGER(1, ADD2(20, 22));
'END'  

Pass by name is similar to pass by reference in C++ or Java in that it allows output to be made to parameters; it also enables Jensen's device. Take for example the below:

'BEGIN'  
    'PROCEDURE' INC(A, B);
    'INTEGER' A, B;
    'BEGIN'
        A := A + 1;
        B := B + 1;
    'END'

    'INTEGER' 'ARRAY' X(/10/);
    'INTEGER' J;

    X(/1/) := 10;
    X(/2/) := 20;

    J := 1;
    INC(J, X(/J/));

    OUTINTEGER(1, J);
    OUTINTEGER(1, X(/2/));
'END'  

This will print 2 (as J has been incremented by the line A := A + 1) and 21 (as X[J] was passed in by name, it was evaluated as X[2] in the line B := B + 1).

Standard functions and input/output

There are a small number of standard functions defined by the language, mostly mathematical (eg ABS, SIGN, SQRT, SIN, LN). The ENTIER function accepts a real number as parameter and returns an integer.

No input/output functions are defined at all in the standard, due to the desire for the language to be device independent and as at the time there was no common agreement of what input/output facilities could be provided across all available hardware. The IBM compiler provides PUT and GET for low level I/O, SYSACT for stream manipulation and a number of functions for input or output of variables, eg ININTEGER, OUTREAL.

Further information

The Revised Report on the Algorithmic Language Algol 60 is the standard for the language. Donald Knuth wrote an article on the remaining troublespots in ALGOL 60 on some of the ambiguities in the standard.

The original IBM documentation for the compiler contains most of the text of the Revised Report annotated with examples using IBM's representation.

Updated 6-Feb-2015 to fix comment syntax