Let's look at ALGOL W in more detail, focusing on the differences compared to ALGOL 60.

Representation

ALGOL W is free format and case insensitive, though the convention was to have keywords in lower case and identifiers Like_This. Identifiers can be up to 255 characters long.

Keywords are reserved words so no stropping is required. A standard EBCDIC character set is used so there is no need for a different reference and hardware representation.

As well as the comment syntax from ALGOL 60, comments can be started with % and then terminated with either % or ;.

The final statement in a program or separately compiled unit (ie the last end) should end with a period.

% This is an ALGOL W program %
begin  
    integer Population_Count;
end.  

New data types

As well as the existing types from ALGOL 60 such as real and integer, ALGOL W provides long real, complex, bit and proper string types:

begin  
    complex C;
    bits B;
    string(50) S;
    c := 1 + 2I;
    b := #0000010F;
    s := "Hello, world";
end.  

Bit values are padded to 32 bits. String variables have to be declared with their length, such as 50 above; if the length is not provided the default is 16.

New operators

div does integer division and rem yields the remainder after division. As well as the logical operators like and, there are also shl and shr for bitwise left and right shifts.

begin  
    write(#1 shl 2);
    write(42 rem 20);
end.  

The above will print #00000004 and 2.

Records and references

Records group together simple variables like a struct in C. References can point to records but not fundamental types. A reference can be initialised, at which point memory for the record is allocated. After initialisation, fields can be accessed by field(variable).

begin  
    record Person(integer Age; real Height; string(40) Name);
    reference(Person) P, Q;
    P := Person(30,, "N Wirth");
    Q := Person;
    Age(Q) := 42;
    write(Name(P));
    write(Age(Q));
end.  

Note for the initialisation of P we leave Height uninitialised, and although memory for Q is allocated it is not initialised at all. This example will print "N Wirth" and 42.

References can be used to point at records but not fundamental types. null can be used to refer to an non-existent record. So a simple linked list could be defined as below, which will print 20.

begin  
    record List(integer Data; reference(List) Next);
    reference(List) L;
    L := List(10, null);
    Next(L) := List(20, null);
    write(Data(Next(L)));
end.  

A reference can point to more than one type of record; which one can be determined at run time with the is operator.

begin  
    record A(real Aa);
    record B(integer Bb);
    reference(A, B) R, S;
    R := A(3.0);
    S := B(4);
    S := R;
    if S is A then write("Got an A") else write("Got a B");
end.  

The above will print "Got an A". I think there is no garbage collector, so the memory allocated for the B is leaked.

while and case

As well as the three types of for statements from ALGOL 60, ALGOL W has a while statement. The below will print 256.0

begin  
    real X;
    X := 2.0;
    while X < 100 do
    begin
        X := X * X;
    end;
    write(X);
end.  

case allows switching by integer value; the below will print "Two". Note there is no default case, so if J < 1 or > 4 there will be a runtime error.

begin  
    integer J;
    string(10) Word;
    J := 2;
    Word := case J of ("One", "Two", "Three", "Four");
    write(Word);
end.  

Procedures

The syntax for procedures differs from ALGOL 60 as types and calling conventions are specified in the function header:

begin  
    real procedure Fn(real X; integer value Y);
    begin
        X * Y
    end;
    write(Fn(3.0, 2));
end.  

The default calling convention, as used in the above, is by name, but *ALGOLW will give you a warning suggesting you use another convention instead.

Putting value after the type means pass by value. There is a new calling convention, result, which is for pass-out variables. value results allows both pass-in and pass-out without the side effects of pass by name.

begin  
    procedure P1(integer value A; integer result B; real value result C);
    begin
        A := 10;
        B := A;
        C := C + A
    end;

    integer A, B;
    real C;
    A := 1; B := 2; C := 3.0;

    P1(A, B, C);
    write(A, B, C);
end.  

The above will display 1, 10, 13.

Input/Output and library

There's an extensive input/output library that has been customised for MTS.

Basic input/output allows reading and writing each from a single channel. The below program will expect input formatted like this:

1001 "Niklaus" "Wirth"  
Inventor of ALGOL W  
begin  
    integer ID;
    string(20) First, Last;
    string(80) Description;

    read(ID);
    readon(First, Last);
    readcard(Description);
end.  

More complex formatting and carriage control can be specified. There is also support for reading/writing to more than one channel, and indexed access.

The standard library contains mathematical functions and access to operating system information like time and date.

Further information

MTS volume 16 describes the language and the MTS extensions in detail.

Another introduction to the language can be found at everything2.