1 Informal Description

Rationale

Most programming languages widely used today provide short-circuited versions of the logical OR and AND functions. In many cases these are the only versions of the logical operators which are provided. They allow to express many conditions in a brief and clean way, relying on the control flow logic implied by the operators. This is particularly rewarding when the operations get nested, as is often the case.

The operands of an Algol 68 formula are always elaborated collaterally. The standard logical operators and and or are not an exception. When faced with a situation where short-circuited logic is required, one is forced to make the control flow explicit.

Let us suppose we have a string value and we wish to determine whether the last character stored within it is a newline character. However, the string value may be empty, so we have to check its size before indexing it in order to avoid a bounds run-time error.

As discussed above, using the standard logical operators are not an option, because of collateral elaboration of the operands of a formula:

if upb str > 0 and str[upb str] = "'/" # Wrong #
then c ... c fi

Instead, we have to encode the lazy logic by mean of explicit control flow clauses. An obvious clumsy and verbose way to do this is something like:

if upb str > 0
then if str[upb str] = "'/"
     then C ... C fi
fi

A much better idiom is to use the abbreviated style of conditional clause this way:

if (upb str > 0 | str[upb str] = "'/" | false)
then C ... C fi

If the implementation we use guarantees that the skip boolean value is always false, like GCC does, then we can use an even more compact (if non-portable) version of the idiom:

if (upb str > 0 | str[upb str] = "'/")
then C ... C fi

When it is a short-circuited OR what is needed, it is always possible to negate the first operand and use the idiom above. For example, if we want to check whether a given name is nil or if its referred value is zero, we can do:

if (ptr :/=: nil | ptr = 0)
then C ... C fi

The andth and orel pseudo-operators

This extension, which comes from ALGOL68RS and also the Algol 68 Genie interpreter, takes the form of two constructs that take the form of pseudo-operators:

tertiary1 andth tertiary2

Meaning “and then”, elaborates tertiary1 and if it yields true, then elaborates tertiary2 and yields its value. Otherwise it yields false.

tertiary1 orel tertiary2

Meaning “or else”, elaborates tertiary1 and if it yields false, then elaborates tertiary2 and yields its value. Otherwise it yields true.

Note that the way the pseudo-operators are implemented, they have a lower priority than any proper operator. This means that care must be given when using them with the and and or operators. For example, the following code almost certainly doesn’t elaborate as intended, and it may result in nil being dereferenced:

if ptr :/=: nil andth ptr => 0 and ptr <= 10
then C ... C fi

Parenthesis are necessary to assure the intended safe semantics:

if ptr :/=: nil andth (ptr => 0 and ptr <= 10)
then C ... C fi