Variables and Types in ALGOL 68
Learn about ALGOL 68's powerful mode system — its unique approach to variables, types, and type composition with practical Docker-ready examples
Introduction
ALGOL 68 takes a distinctive approach to variables and types through what it calls its mode system. Rather than using the word “type,” ALGOL 68 uses “mode” to describe the nature of a value. This terminology signals that the type system is richer and more orthogonal than in most languages of its era — or even many languages that followed.
In ALGOL 68, every value has a mode, and the language enforces these modes strictly at compile time. This is static, strong, structural typing in action: the compiler checks modes before the program runs, type coercions follow precise rules, and the structure of a mode determines compatibility, not its name. Understanding modes is the key to understanding ALGOL 68.
What makes this particularly interesting is how ALGOL 68’s mode system prefigured features that became widespread only decades later: structural typing, union types (called “united modes”), and user-definable type synonyms (via MODE declarations). This tutorial covers the foundational mode concepts you will encounter in every ALGOL 68 program.
Declaring Variables and Basic Modes
In ALGOL 68, a variable declaration places the mode before the name. Assignment uses := (the walrus operator, though ALGOL 68 predates that name). The basic primitive modes are:
INT— integer (whole number)REAL— floating-point numberBOOL— boolean (TRUEorFALSE)CHAR— single characterSTRING— a sequence of characters (technically a flexible array ofCHAR)
Create a file named variables.a68:
BEGIN
# Integer variables #
INT count := 42;
INT year := 1968;
# Real (floating-point) variables #
REAL pi := 3.14159265;
REAL temperature := -17.5;
# Boolean variables #
BOOL is historic := TRUE;
BOOL is mainstream := FALSE;
# Character and string variables #
CHAR initial := "A";
STRING language name := "ALGOL 68";
# Print the values #
print(("count = ", count, new line));
print(("year = ", year, new line));
print(("pi = ", pi, new line));
print(("temperature = ", temperature, new line));
print(("is historic = ", is historic, new line));
print(("initial = ", initial, new line));
print(("language name = ", language name, new line))
END
A few ALGOL 68 syntax notes:
#begins and ends comments (ALGOL 68 uses#as a comment delimiter):=is the assignment operator;=is used for equality testing only- Semicolons separate statements within a
BEGIN...ENDblock - Identifiers may contain spaces —
language nameis a single identifier, which is a unique ALGOL 68 feature
Constants and Identity Relations
ALGOL 68 makes a clear distinction between variables (which hold references to values) and constants (identity relations that directly name a value). A constant is declared with = instead of :=:
Create a file named variables_constants.a68:
BEGIN
# Constants (identity relations) — cannot be reassigned #
INT max count = 100;
REAL avogadro = 6.02214076e23;
BOOL debug mode = FALSE;
STRING version = "3.1.2";
# Variables — can be reassigned #
INT counter := 0;
counter := counter + 1;
counter := counter + 1;
print(("max count = ", max count, new line));
print(("avogadro = ", avogadro, new line));
print(("version = ", version, new line));
print(("counter after increments = ", counter, new line));
# ALGOL 68 enforces the distinction:
# max count := 200 would be a compile error — max count is not a variable #
print(("Constants cannot be reassigned — enforced at compile time", new line))
END
This distinction reflects ALGOL 68’s careful separation between l-values (locations in memory) and r-values (values). Variables are references that can be dereferenced and updated; constants name values directly. ALGOL 68 was one of the first languages to articulate this distinction formally.
User-Defined Modes (Type Synonyms)
One of ALGOL 68’s most powerful features is the MODE declaration, which creates a new name for any existing mode. This is structural typing: a MODE declaration creates an alias, not a distinct incompatible type.
Create a file named variables_modes.a68:
BEGIN
# Define mode synonyms #
MODE TEMPERATURE = REAL;
MODE COUNT = INT;
MODE NAME = STRING;
MODE FLAG = BOOL;
# Use the new mode names #
TEMPERATURE boiling point = 100.0;
TEMPERATURE freezing point = 0.0;
COUNT population := 8000000000;
NAME language = "ALGOL 68";
FLAG is active = TRUE;
print(("Boiling point: ", boiling point, " C", new line));
print(("Freezing point: ", freezing point, " C", new line));
print(("World population: ", population, new line));
print(("Language: ", language, new line));
print(("Active: ", is active, new line));
# Because MODE creates structural aliases, TEMPERATURE and REAL are compatible #
REAL raw temp := boiling point;
print(("Raw temp (as REAL): ", raw temp, new line))
END
User-defined modes make programs self-documenting and reveal intent. A TEMPERATURE variable communicates far more than a bare REAL.
Type Coercions and the Coercion Hierarchy
ALGOL 68’s type system includes a set of precisely defined coercions — automatic conversions the compiler performs when context requires it. These are not implicit casts; they follow strict rules depending on the “syntactic position” (context) of an expression.
The key coercions relevant to variables are:
- Widening:
INTwidens toREALin numeric contexts - Dereferencing: A variable (reference) is automatically dereferenced to yield its value
Create a file named variables_coercions.a68:
BEGIN
# Widening: INT is automatically coerced to REAL where needed #
INT whole := 7;
REAL fraction := whole; # INT widened to REAL automatically #
print(("INT value: ", whole, new line));
print(("Widened to REAL: ", fraction, new line));
# Explicit conversion using standard procedures #
REAL pi approx := 3.14159;
INT truncated = ENTIER pi approx; # ENTIER truncates toward negative infinity #
INT rounded = ROUND pi approx; # ROUND rounds to nearest integer #
print(("pi approx: ", pi approx, new line));
print(("ENTIER (truncate): ", truncated, new line));
print(("ROUND (nearest): ", rounded, new line));
# String and character operations #
STRING greeting := "Hello";
INT length = UPB greeting; # UPB gives the upper bound (length) of a string #
print(("Greeting: ", greeting, new line));
print(("Length: ", length, new line));
# Character arithmetic #
CHAR letter a = "a";
INT char code = ABS letter a; # ABS converts a CHAR to its integer code #
CHAR next letter = REPR (char code + 1); # REPR converts back to CHAR #
print(("Letter: ", letter a, new line));
print(("Char code: ", char code, new line));
print(("Next letter: ", next letter, new line))
END
ENTIER (from French for “whole”) and ROUND are ALGOL 68’s standard conversion procedures — remnants of the language’s European academic origins. ABS and REPR handle the CHAR/INT bridge.
Running with Docker
| |
Expected Output
Running variables.a68:
count = +42
year = +1968
pi = +3.14159265000000e +0
temperature = -1.75000000000000e +1
is historic = T
initial = A
language name = ALGOL 68
Running variables_constants.a68:
max count = +100
avogadro = +6.02214076000000e +23
version = 3.1.2
counter after increments = +2
Constants cannot be reassigned — enforced at compile time
Running variables_modes.a68:
Boiling point: +1.00000000000000e +2 C
Freezing point: +0.00000000000000e +0 C
World population: +8000000000
Language: ALGOL 68
Active: T
Raw temp (as REAL): +1.00000000000000e +2
Running variables_coercions.a68:
INT value: +7
Widened to REAL: +7.00000000000000e +0
pi approx: +3.14159000000000e +0
ENTIER (truncate): +3
ROUND (nearest): +3
Greeting: Hello
Length: +5
Letter: a
Char code: +97
Next letter: b
Note on ALGOL 68 output format: Algol 68 Genie prints integers with leading spaces and a
+/-sign, and reals in scientific notation with explicit sign on the exponent. This is standard ALGOL 68 behavior — theprintfprocedure with format strings gives more control over formatting.
Key Concepts
- Modes, not types: ALGOL 68 calls its types “modes” —
INT,REAL,BOOL,CHAR, andSTRINGare the fundamental primitive modes - Declaration syntax: Mode precedes name —
INT count := 42notcount: int = 42orint count = 42 - Variables vs. constants:
:=creates a mutable variable;=creates an identity relation (constant) — the compiler enforces this distinction - Identifiers with spaces: ALGOL 68 uniquely allows spaces in identifiers —
language nameis a single identifier, not two tokens MODEdeclarations: Create structural aliases for any mode; useful for self-documenting code without creating incompatible types- Coercion hierarchy:
INTwidens toREALautomatically where needed; explicit conversion usesENTIER,ROUND,ABS, andREPR ENTIERvs.ROUND:ENTIERtruncates toward negative infinity (floor),ROUNDrounds to nearest integer — both convertREALtoINT- String length via
UPB: Strings are flexible arrays ofCHAR;UPB(upper bound) returns the length, a pattern that extends to all ALGOL 68 arrays
Running Today
All examples can be run using Docker:
docker pull codearchaeology/algol68:latest
Comments
Loading comments...
Leave a Comment