Structured programming The
structured programming movement aimed to eliminate the need for and use of the goto statement by introducing
control structures to a language such as: ; Selection: Such as the conditional statement (i.e. if-then-else) and the
switch statement ; Iteration: Loop statements such as the
for loop,
while loop and
do while loop. ; Premature exit: terminate execution of control structure or a single iteration ::break ::iterate ::leave :Some languages, e.g.,
PL/I, allow naming the control structure. : foo: do i=1 to 10; if i=7 then iterate foo; x(i) = 3; end; These new language mechanisms replaced equivalent control flow that previously would have been written using goto. The switch statement replaces the computed goto in which the instruction to jump to is determined dynamically (conditionally). Under certain conditions, it is possible to eliminate local goto statements of legacy programs by replacing them with multilevel loop exit statements.
Exception handling In practice, a strict adherence to the basic three-structure template of structured programming yields highly nested code, due to inability to exit a structured unit prematurely, and a
combinatorial explosion with quite complex program state data to handle all possible conditions. Two solutions have been generally adopted: a way to exit a structured unit prematurely, and more generally
exception handling. Both of these go
up the structure, returning control to enclosing blocks or functions, but do not jump to arbitrary code locations. These are analogous to the use of a return statement in non-terminal position – not strictly structured, due to early exit, but a mild relaxation of the strictures of structured programming. In C,
break and continue allow one to
terminate a loop or
continue to the next iteration, without requiring an extra while or if statement. In some languages multi-level breaks are also possible. For handling exceptional situations, specialized
exception handling constructs were added, such as -- in Java. The throw-catch exception handling mechanisms can also be easily abused to create non-transparent control structures, just like goto can be abused.
Tail call In a paper delivered to the ACM conference in Seattle in 1977,
Guy L. Steele summarized the debate over the goto and structured programming, and observed that procedure calls in the tail position of a procedure can be most optimally treated as a direct transfer of control to the called procedure, typically eliminating unnecessary stack manipulation operations. Since such "tail calls" are very common in
Lisp, a language where procedure calls are ubiquitous, this form of optimization considerably reduces the cost of a procedure call compared to the goto used in other languages. Steele argued that poorly implemented procedure calls had led to an artificial perception that the goto was cheap compared to the procedure call. Steele further argued that "in general procedure calls may be usefully thought of as goto statements which also pass parameters, and can be uniformly coded as
machine code JUMP instructions", with the machine code stack manipulation instructions "considered an optimization (rather than vice versa!)". Steele cited evidence that well optimized numerical algorithms in Lisp could execute faster than code produced by then-available commercial Fortran compilers because the cost of a procedure call in Lisp was much lower. In
Scheme, a Lisp dialect developed by Steele with
Gerald Jay Sussman, tail call optimization is mandatory. Although Steele's paper did not introduce much that was new to computer science, at least as it was practised at MIT, it brought to light the scope for procedure call optimization, which made the modularity-promoting qualities of procedures into a more credible alternative to the then-common coding habits of large monolithic procedures with complex internal control structures and extensive state data. In particular, the tail call optimizations discussed by Steele turned the procedure into a credible way of implementing iteration through single
tail recursion (tail recursion calling the same function). Further, tail call optimization allows
mutual recursion of unbounded depth, assuming tail calls – this allows transfer of control, as in
finite-state machines, which otherwise is generally accomplished with goto statements.
Coroutine A
coroutine is a more radical relaxation of structured programming, allowing not only multiple exit points (as in returns in non-tail position), but also multiple entry points, similar to goto statements. A coroutine is more restricted than goto, as it can only
resume a currently running coroutine at specified points – continuing after a yield – rather than jumping to an arbitrary point in the code. A limited form of coroutine is a
generator. Even more limited is a
closure – a function which maintains state (via
static variables), but not execution position. A combination of state variables and structured control, notably an overall switch statement, can allow a function to resume execution at an arbitrary point on subsequent calls, and is a structured alternative to goto in the absence of coroutines. This is a common idiom in C, for example.
Continuation A
continuation is similar to a goto in that it transfers control from an arbitrary point in the program to a marked point. A continuation is more flexible than goto in that it can transfer control out of the current function, something that a goto cannot do in most structured programming languages. In those language implementations that maintain stack frames for storage of local variables and function arguments, executing a continuation involves adjusting the program's
call stack in addition to a jump. The
longjmp function of the
C programming language is an example of an escape continuation that may be used to escape the current context to a surrounding one. The
Common Lisp GO operator also has this stack unwinding property, despite the construct being
lexically scoped, as the label to be jumped to can be referenced from a
closure. In
Scheme, a continuation can move control from an outer context to an inner one. This enables writing control structures such as coroutines and cooperative multitasking. ==See also==