Rather than using pass-by-reference for input/output parameters, Algol used the more powerful mechanism of pass-by-name.
In essence, you can pass in the symbolic "name"; of a variable, which allows it both to be accessed and updated.
For example, to double the value of
C[j], you can
pass its name (not its value) into the following procedure.
procedure double(x); real x; begin x := x * 2 end;
In general, the effect of pass-by-name is to
substitute the argument expressions in a procedure call
for the corresponding parameters in the body of the
double(C[j]) is interpreted as
C[j] := C[j] * 2.
Technically, if any of the variables in the called procedure clash with the caller's variables, they must be renamed uniquely before substitution.
Implications of the pass-by-name mechanism:
Passing expressions into a routine so they can be repeatedly evaluated has some valuable applications.
Consider calculations of the form: "sum xi
for all i from 1 to n."
How could a routine
written so that we could express this as
Sum(i, 1, n, x[i]*i)?
Using pass-by-reference or pass-by-value, we cannot
do this because we would be passing in only a single
x[i]*i, not an expression which
can be repeatedly evaluated as "
is passed in without evaluation.
real procedure Sum(j, lo, hi, Ej); value lo, hi; integer j, lo, hi; real Ej; begin real S; S := 0; for j := lo step 1 until hi do S := S + Ej; Sum := S end;Each time through the loop, evaluation of
Ejis actually the evaluation of the expression
procedure swap (a, b); integer a, b, temp; begin temp := a; a := b; b:= temp end;
temp := x; x := y; y := temp
temp := i; i := x[i]; x[i] := tempIt doesn't work! For example:
It is very difficult to write a correct
procedure in Algol.
boolean procedure and (x, y); boolean x, y; begin if x then return y else return false end;Here,
yis not evaluated if
Thunks are parameterless procedures used to implement pass-by-name.
Essentially a thunk is set up to return a pointer to the current location represented by a parameter.
Thunks can be simulated in (extended) Pascal using procedure types.
For example, to simulate the argument expressions
passed using pass-by-name, the following thunks can be set up.
TYPE IntVarAddress = ^ INTEGER; RealVarAddress = ^ REAL; FUNCTION iThunk () : IntVarAddress; BEGIN iThunk := ADDRESS(i) END;
FUNCTION XiThunk () : RealVarAddress; VAR expi : REAL; BEGIN expi := x[i] * i; XiThunk := ADDRESS(expi) END;
iThunk will always return the same memory location,
XiThunk will return a memory location dependent on
the current value of
Now, the Algol expression
Sum(i, 1, n, x[i])
could be rewritten in (extended)
Sum(iThunk, lo, hi, XiThunk)
Sum function is defined as follows.
FUNCTION Sum(jThunk : FUNCTION () : IntVarAddress; lo, hi : INTEGER; EjThunk : FUNCTION () : RealVarAddress); VAR S : REAL; BEGIN S := 0; jThunk()^ := lo; WHILE jThunk()^ <= hi DO BEGIN S := S + EjThunk()^; jThunk()^ := jThunk()^ + 1 END; Sum := S END;