Algol 68 structures
last modified November 13, 2026
A structure groups several values of possibly different modes into one value.
Algol 68 declares the shape of a structure once with MODE and
STRUCT, and then treats the new mode like any other: it may be
used for variables, rows, parameters, and results. This article describes the
declaration, the selection of a field with OF, nested structures,
and the operations that work on a whole structure.
Defining a structured mode
MODE introduces a name for a mode, and STRUCT lists
the fields with their modes. A value of the new mode is written as a
parenthesised list of field values in the order of the declaration, and a
field is read or assigned with OF.
MODE POINT = STRUCT(INT x, INT y); BEGIN POINT p := (3, 4); print((whole(x OF p, 0), " ", whole(y OF p, 0), newline)); x OF p := 10; print((whole(x OF p, 0), newline)); POINT q = (1, 2); print((whole(x OF q + x OF p, 0), newline)) END
The variable holds two integers, and x OF p is a name of the
first one, which is why the assignment x OF p := 10 changes the
structure in place. Selection binds tighter than the arithmetic, so
x OF q + x OF p adds the two x fields and yields 11.
The display (3, 4) has no mode of its own: it takes the mode from
the declaration on the left.
$ a68g basic.a68 3 4 10 11
Structures inside structures
A field may itself have a structured mode, and the fields of that field are
reached by writing OF again. The inner display is nested in the
outer one at the position of the field.
MODE DATE = STRUCT(INT year, INT month, INT day);
MODE PERSON = STRUCT(STRING name, DATE born);
BEGIN
PERSON p := ("Ada", (1815, 12, 10));
print((name OF p, newline));
print((whole(year OF born OF p, 0), newline));
print((whole(day OF born OF p, 0), newline))
END
The chain reads from the outside in: born OF p selects the date
and year OF then selects the year of that date. The declaration
of PERSON must come after the declaration of DATE,
because the mode has to be known when it is used.
$ a68g nested.a68 Ada 1815 10
Rows of structures
The element mode of a row may be a structure, so a row is a compact way to hold a table of records. Because the elements are variables, their fields can be assigned through a subscript.
MODE POINT = STRUCT(INT x, INT y);
BEGIN
[1:3] POINT points := ((0, 0), (3, 4), (6, 8));
FOR i TO 3 DO
print((whole(x OF points[i], 0), ",", whole(y OF points[i], 0), " "))
OD;
print((newline));
x OF points[2] := 30;
print((whole(x OF points[2], 0), newline))
END
The denotation has three displays, one for each element. The loop prints the
pairs, and the assignment then changes the x field of the second
point without touching the other elements. Each element is a complete
structure of its own, so a change to one element never reaches another.
$ a68g rows.a68 0,0 3,4 6,8 30
Structures as parameters
A structured value may be passed to a procedure like any other value. The parameter has the mode of the structure and receives a copy, so the procedure can read the fields but cannot change the caller's variable.
MODE POINT = STRUCT(INT x, INT y); PROC distance = (POINT p) REAL: sqrt(x OF p ** 2 + y OF p ** 2); BEGIN POINT p := (3, 4); print((fixed(distance(p), 0, 1), newline)) END
The procedure computes the distance of the point from the origin, which is 5
for the pair 3 and 4. The fields are integers and sqrt accepts an
integer argument, so the square of the distance is formed in integer
arithmetic and the square root yields the value of the declared mode
REAL, which fixed prints with one decimal.
$ a68g distance.a68 5.0
Assignment copies the whole structure
Assigning one structure to another copies every field. The two variables then hold independent values, so a change to one of them is not visible through the other.
MODE POINT = STRUCT(INT x, INT y); BEGIN POINT a := (1, 2); POINT b := a; x OF b := 99; print((whole(x OF a, 0), " ", whole(x OF b, 0), newline)) END
The second declaration copies the two integers into a new structure, and the assignment changes only the copy's first field. The original still holds 1. A structure that must be shared has to be reached through a reference, which the references and the heap article describes.
$ a68g copy.a68 1 99
Reference parameters
A parameter declared with REF designates the caller's structure
instead of copying it, so the procedure can assign to its fields. The
argument must be a name of the required mode.
MODE POINT = STRUCT(INT x, INT y); PROC move = (REF POINT p, INT dx, INT dy) VOID: ( x OF p +:= dx; y OF p +:= dy ); BEGIN POINT p := (3, 4); move(p, 10, -1); print((whole(x OF p, 0), " ", whole(y OF p, 0), newline)) END
The procedure adds the offsets to the two fields of the caller's variable.
The compound assignments +:= work on the selected fields exactly
as they work on plain integers, and the call changes the point to 13 and 3.
$ a68g refproc.a68 13 3
Fields that are rows
A field may have a row mode, and the brackets of a subscript follow the selection. Because selection and subscripting are separate operations, the selected row has to be parenthesised before it is indexed.
MODE POLY = STRUCT([1:3] INT coef, INT degree); BEGIN POLY p := ((1, 2, 3), 2); print((whole((coef OF p)[1], 0), " ", whole((coef OF p)[3], 0), newline)); (coef OF p)[2] := 9; print((whole((coef OF p)[2], 0), " ", whole(degree OF p, 0), newline)) END
The polynomial has three coefficients and a degree. Writing
coef OF p[1] without parentheses is read as
coef OF (p[1]) and rejected, because p is not a row
of polynomials. With the parentheses the selection yields the row of
coefficients and the subscript picks one of them.
$ a68g arrayfield.a68 1 3 9 2
Comparing structures
There is no predeclared = operator for a structured mode: writing
a = b produces an error about an undeclared operator. Equality is
written by comparing the fields, either in the program or in a procedure.
MODE POINT = STRUCT(INT x, INT y); PROC same = (POINT a, POINT b) BOOL: x OF a = x OF b AND y OF a = y OF b; BEGIN POINT a := (1, 2), b := (1, 2), c := (1, 3); print((same(a, b), " ", same(a, c), newline)); b := c; print((same(a, b), newline)) END
The procedure compares both fields and returns a boolean, so the first line
reports that a equals b but not c. After
the whole-structure assignment b holds the values of
c, and the second line is false. A comparison written this way
also states which fields matter.
$ a68g compare.a68 T F F
Printing a structure
print accepts a structured value directly and prints its fields
one after another, in the same layout it uses for the individual modes. This
is convenient for quick inspection but not for formatted output.
MODE POINT = STRUCT(INT x, INT y); MODE LINE = STRUCT(POINT from, POINT to); BEGIN POINT p := (3, 4); LINE l := ((0, 0), (6, 8)); print((p, newline)); print((l, newline)) END
Each integer is printed in a fixed field of eleven characters, with spaces in front of the sign, and the nested line prints the four coordinates in the order of the declaration. To control the spacing, a program prints the fields itself or uses the formatted transput described later.
$ a68g printstruct.a68
+3 +4
+0 +0 +6 +8
Next steps
The modes article places STRUCT
among the other compound modes. The unions
article shows how a value may hold one of several structures, and
references and the heap explains how a structure
field may point to another structure. The
rows article describes the row modes that may
appear as fields.
Source
Revised Report on the Algorithmic Language Algol 68
In this article we have defined structured modes, selected and assigned their fields, nested one structure in another, stored structures in rows, passed them to procedures by value and by reference, indexed a row field, compared structures field by field, and printed them. The unions article continues with values that may take one of several modes.
Author
List all Algol 68 tutorials.