"Call by name" is conceptually the simplest form of parameter passing:
the effect of a procedure call is as if all occurrences of the formal
parameter in the procedure body were textually replaced by copies of
the actual parameter in the call and then the modified procedure body
is executed. (There may be some renaming of local variables
to avoid conflict).
"Call by value" is slightly *more* complicated in that the actual
parameter is first evaluated, and then the formal parameter
is replaced by the value of the actual parameter.
Call by name is similar to lazy evaluation in that the parameter
is only evaluated when it is actually used in the procedure body.
Passing the expression 1/0 by value will give an error,
but passing 1/0 by name or by lazy evaluation will only give an error
if the formal parameter is actually used in the procedure body.
Languages with lazy evaluation do not allow assignment to the parameter,
but otherwise, lazy evaluation without memoization is equivalent
to call by name. To take Seymour's example of a routine to implement
Simpson's Method: pass the integrand as a lazy parameter
and pass the integration variable by reference. Assigning to
the integration variable in the procedure body updates
the variable in the caller's environment. Accessing the integrand
in the procedure body evaluates the expression in the caller's
environment using the updated integration variable.
(Note: this would not work with memoized lazy evaluation!)
In modern languages, first class functions can do everything
that call by name could do. A routine for Simpson's Method
takes the function to be integrated as a function parameter.
If we want to implement the effect of accessing and updating
an expression passed by name (for example, passing i and A[i]
by name to a subroutine which will update the whole array A)
we can pass two function parameters for A: a "getter" function
getA(i) which returns the value of A[i] and a "setter" function
setA(i, x) which sets A[i] := x. This implementation is in fact
very similar to how call by name was implemented in the early
Algol 60 compilers. (Of course, for this simple case you could
just pass the whole array as a reference parameter).
Instead of the "trick" of Jensen's Device (where we pass a function
to a subroutine by passing an expression and one or more
of its free variables by value), in a modern language we just
pass the function, or a lambda expression.
Dr Martin Ward | Email: mar...@gkc.org.uk | http://www.gkc.org.uk
G.K.Chesterton site: http://www.gkc.org.uk/gkc | Erdos number: 4