FOO = F(G(A,B,C,D) + H(A,B,C), G(C,D,A,B)
1 - H(C,D,A), G(D,C,B,A) * H(D,C,B))
becomes
FOO1 G(A,B,C,D) + H(A,B,C)
FOO2 G(C,D,A,B) - H(C,D,A)
FOO3 G(D,C,B,A) * H(D,C,B)
FOO = F(FOO1, FOO2, FOO3)
If someone had asked me whether assignment statements were an agent of modularity in programming languages, I should certainly have replied in the negative before seeing this example.
Similarly, consider the notion of iteration, another useful concept in organizing programs. We are all familiar with the use of WHILE-DO
and its variants, and also with the use of IF-THEN-ELSE
and GOTO
to achieve the same purpose. But, as shown earlier, procedure calls can be an agent of iteration.
While I would hesitate to write
procedure whiledo(condition,statement);
begin if condition then
begin statement;
whiledo(condition,statement)
end
end
whiledo(B,S);
for "WHILE B DO S
", I would not hesitate to write
real procedure sqrt(arg);
value arg; real arg;
begin
real procedure sqrt1(approx);
value approx; real approx;
if abs(arg - approx*approx) < epsilon
then approx
else sqrt1((approx + arg/approx)/2);
sqrt1(arg/2);
end;
knowing, if necessary, that it could be compiled as an iteration rather than as a stack-pushing recursion. Of course, I would prefer not to have to write the "value" declarations, and might prefer some other notation, such as LISP notation, but the essential idea is the same.
It is even possible to use procedure calls to implement conditional expressions, though this has heretofore been largely a curiosity for students of lambda calculus. [Chu41] Similarly, many assignment statements can be modelled and even implemented through the use of procedure calls. I have written two LISP compilers which use procedure calls to implement all assignments and iterations within the compiler. [Ste77a] I have used these compilers to compile themselves, and there seems to have been no demonstrable sacrifice of speed due to the use of procedure calls. Moreover, the code, totalling some seventy pages of source text, has been extremely easy to modify and maintain.
The important point is that for each important programming concept which we have found useful -- modularity, iteration, assignment, conditionals