Coercions & Contexts

A coercion is an implicit change of mode determined at compile time.

27.1 Coercions

A coercion is an implicit change of mode determined at compile time. ALGOL 68 has six (Revised Report):

INT y = x where x is REF INT PROC M → M (calls it)

INT r = roll where roll is PROC INT M → UNION (..., M,...) UNION (INT, REAL) u:= 5

INT → REAL → COMPL; BITS → [] BOOL; same for LONG sizes M → [] M (or REF M → REF [] M) [] INT a = 5 (a row of one element) M → VOID (value discarded) x:= 3; as a statement, f(x);

There is also weak dereferencing, a restricted dereferencing that stops at the last REF (used in weak contexts so that a[i] and x OF p remain assignable).

27.2 The five contexts

Every position in a program has a syntactic context that determines which coercions are allowed:

right side of :=; actual parameters; source of an identity declaration; routine body; the operand of a cast dereferencing, deproceduring, uniting operands of operators dereferencing, deproceduring enquiry clauses (conditions), subscripts, bounds, the procedure in a call deproceduring, weak dereferencing the row in a slice a[i], the structure in a selection x OF p the destination (left side) of :=

Because operands are only firm, widening does not happen there: operators must be declared for each combination (the standard prelude declares + for (INT, REAL), (REAL, INT) etc.). This is also why user-defined operators sometimes need explicit casts.

27.3 Coercions at work

BEGIN
   INT i := 3;
   REAL r := i;                     # strong: dereference i, then widen INT -> REAL #
   PROC INT next = INT: (i +:= 1; i);
   INT a = next;                    # strong: deprocedure (call) next #
   UNION (INT, STRING) u := "text"; # strong: unite STRING into the union #
   [] REAL row = 1;                 # strong: widen 1 to 1.0 then row it to a 1-element row #
   i := 5;                          # voiding of the assignment's result #
   print((r, a, UPB row, newline))
END

27.4 Balancing

In a conditional or case clause whose branches have different modes, the branches are balanced to a common mode (one branch may be in a strong context while the others are coerced to match):

REAL x = (TRUE | 1 | 2.5);     # 1 is widened to REAL #

27.5 Casts

A cast puts a value into a strong context of a stated mode:

REAL (7)                 # INT -> REAL #
REF INT (p) := 3         # stop dereferencing at REF INT (assign through p) #
VOID (f(x))              # discard explicitly #
UNION (INT, REAL) (4)    # explicit uniting #

27.6 Contexts in the grammar

Contexts are not just prose: the two-level grammar (Chapter 38) builds them into the syntax — e.g. the source of an assignation is a "strong MODE unit" and the destination a "soft REF to MODE tertiary". That is how ALGOL 68 resolves, purely syntactically, how many times to dereference.