[IBM68] [DEC69] (One notable exception to this mess is LISP. There are also some extensible algebraic languages available, such as EL/1 [Weg71] [Weg74]; many of these are in fact implemented in a LISP-like manner beneath a veneer of ALGOL-like syntax.) It is generally true that we tend to believe that the expense of a programming construct is proportional to the amount of writer's cramp it causes us (by a "belief" I mean here an unconscious tendency rather than a fervent conviction). Indeed, this is not a bad psychological principle for language designers to keep in mind. We think of addition as cheap partly because we can notate it with a single character: "+
". Even if we believe that a construct is expensive, we will often prefer it to a cheaper one if it will cut our writing effort in half. This is a lesson that practitioners of programming discipline have been trying to sell us, but it is a good one only if our programming languages are designed to cooperate with our natural tendency toward brevity.
In [Dij76,xvii] Dijkstra comments:
"... it therefore hurts me to see the semantics of the repetitive construct
'
while B do S
'defined as that of the call
'
whiledo(B,S)
'of the recursive procedure (described in ALGOL 60 syntax):
procedure whiledo(condition,statement);
begin if condition then begin statement;
whiledo(condition,statement) end
end "
It hurts me too, partly because Dijkstra here uses call-by-name to an indefinite number of levels, but even more because the syntax of ALGOL 60 makes the example twice as frightening as it really is. The LISP version
((LABEL LOOP
(LAMBDA () (IF (NOT B)
(PROGN S (LOOP))))))
is at least slightly less awesome to me (though of course it is still more awesome than simply "while B do S
"). {Note Step Variables}
As an additional defense of the procedure call, it should be pointed out that it constitutes a universal construct when properly implemented. The practitioners of programming discipline point with pride to such theorems as that of Boehm and Jacopini [Boe66], showing that any program can be written using their favored constructs. Such theorems have recently been ballyhooed about to the point of absurdity:
"Structured programming is based on the mathematically proven Structure Theorem." [Nei76]
It has even been demonstrated, as a mathematical curiosity, that IF-THEN-ELSE
can be dispensed with. [Pre75] It ought not be forgotten, however, that procedure calls can easily simulate sequencing, conditionals, and repetition, while the converse is decidedly not true. Even without completely solving the so-called FUNARG
problem [Mos70], a surprising variety of tricks can be played with procedure calls, including dynamic binding and iteration. If the FUNARG
problem is solved, additional tricks are easily played, such as escape