ZetCode

Algol 68 conditionals

last modified November 13, 2026

Algol 68 chooses between branches with an IF clause or a CASE clause, and both are units that produce a value. This article covers the syntax of those clauses, their use as expressions, and the way boolean operators are evaluated, which decides when a test can be safely guarded.

The IF clause

An IF clause starts with a condition, continues with THEN and a unit, and ends with FI. Further tests are introduced with ELIF, and the remaining case with ELSE. The condition is a meek context, so it must have mode BOOL.

ifelse.a68
BEGIN
  INT score = 75;
  IF score >= 90 THEN
    print(("grade A", newline))
  ELIF score >= 75 THEN
    print(("grade B", newline))
  ELSE
    print(("grade C", newline))
  FI
END

The tests run from top to bottom, and the first true one wins. A score of 75 fails the first test and passes the second, so the program prints grade B. The comparison operators are the ones described in the operators article.

$ a68g ifelse.a68
grade B

Without ELSE

The ELSE part is optional. Without it, a false condition simply continues after FI, so the clause is used for its effect rather than for a value. Writing such a clause where a value is required is a mistake even when the implementation accepts it.

noelse.a68
BEGIN
  INT n = 3;
  IF n > 5 THEN print(("large", newline)) FI;
  IF n < 5 THEN print(("small", newline)) FI
END

Only the second test succeeds, so only small is printed. A branch that does nothing can be written as SKIP, which is the empty unit and keeps the structure of the clause visible.

$ a68g noelse.a68
small

Conditionals as values

When both branches produce a value of the same mode, the whole IF clause has that mode and can be used in a declaration or an argument. The compact conditional clause, (condition | then-value | else-value), does the same with less punctuation.

ifvalue.a68
BEGIN
  INT n = 7;
  INT doubled = IF ODD n THEN 2 * n ELSE n FI;
  print((whole(doubled, 0), newline));
  print(((n > 5 | "big" | "small"), newline))
END

Both branches of the first clause produce an INT, so doubled is initialised with 14. The second line uses the compact form to choose between two strings. The compact form is convenient for short choices, while the full IF form is clearer when a branch contains several statements.

$ a68g ifvalue.a68
14
big

Nested conditionals

A branch may contain another IF clause. Each clause is closed by its own FI, so the structure is explicit and there is no dangling-else ambiguity.

nested.a68
BEGIN
  INT a = 5, b = 10;
  IF a > 0 THEN
    IF b > a THEN
      print(("b is larger", newline))
    ELSE
      print(("a is not smaller", newline))
    FI
  ELSE
    print(("a is not positive", newline))
  FI
END

The outer test succeeds, so the inner clause runs; the inner test also succeeds and the program prints b is larger. Because every clause ends with FI, the inner ELSE belongs to the inner IF without any doubt.

$ a68g nested.a68
b is larger

How boolean operators evaluate

AND and OR are ordinary dyadic operators, so both of their operands are elaborated before the result is computed. They do not short-circuit: a procedure call on the right-hand side runs even when the left-hand side already decides the result.

shortcircuit.a68
PROC check = BOOL: (print(("checked", newline)); TRUE);

BEGIN
  IF FALSE AND check THEN print(("both true", newline)) FI;
  IF TRUE OR check THEN print(("at least one true", newline)) FI
END

The procedure prints its line each time it is called. Both calls happen: the first test prints checked and then fails, and the second prints checked and then succeeds. Only at least one true is printed as a result, but the side effect of the second operand appeared twice.

$ a68g shortcircuit.a68
checked
checked
at least one true

Guarding a test

When the second test must not run, the guard is written as a nested IF instead of an AND. The inner clause is elaborated only when the outer condition is true.

guard.a68
PROC risky = BOOL: (print(("evaluated", newline)); TRUE);

BEGIN
  IF FALSE THEN
    IF risky THEN SKIP FI
  FI;
  print(("guarded", newline))
END

The outer condition is false, so the inner clause never runs and evaluated is never printed. This pattern is used when the second test depends on a value that the first test has to check, such as an index that must be within bounds before the row is read.

$ a68g guard.a68
guarded

CASE clauses

A CASE clause selects one of several units according to an integer. The units follow IN, are separated by commas, and the clause ends with ESAC. An optional OUT part handles values that no listed unit covers.

case.a68
BEGIN
  INT n = 2;
  CASE n IN
    print(("one", newline)),
    print(("two", newline))
  OUT
    print(("other", newline))
  ESAC;
  INT value = CASE n IN 10, 20, 30 OUT 0 ESAC;
  print((whole(value, 0), newline))
END

The first clause selects the second unit and prints two. The second clause is used as a value: the selected unit yields the integer 20, which is assigned to value. In both forms the units are separated by commas, because the clause chooses one of them rather than performing all of them.

$ a68g case.a68
two
20

Values outside the listed choices

Without an OUT part, a case clause does nothing when its integer falls outside the listed choices. The program continues after ESAC, which is why a case clause used for its effect should usually include OUT.

caseout.a68
BEGIN
  CASE 9 IN
    print(("one", newline))
  ESAC;
  print(("after the case", newline))
END

The value 9 selects nothing, so only the line after the clause is printed. The behaviour is different when the clause is used as a value: there is no branch to yield a value, and Genie 2.8.4 accepts the clause but yields a value that no branch produced. A case clause in that position should therefore include OUT, or list every integer it can receive.

$ a68g caseout.a68
after the case

Next steps

The operators article explains the boolean operators and their priorities, and the program structure article places conditionals among the other clause forms. Algol 68 basics shows loops next to conditionals, and coercions explains why a condition needs a boolean.

Source

Revised Report on the Algorithmic Language Algol 68

The Algol 68 Genie project

In this article we have written IF clauses with ELIF and ELSE, used conditionals as values, nested them, examined the evaluation of AND and OR, guarded a test with an inner clause, and selected branches with CASE. The operators article provides the formulas that these conditions are built from.

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.