ZetCode

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.

basic.a68
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.

nested.a68
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.

rows.a68
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.

distance.a68
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.

copy.a68
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.

refproc.a68
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.

arrayfield.a68
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.

compare.a68
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.

printstruct.a68
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

The Algol 68 Genie project

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

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Algol 68 tutorials.