Structured Programming Considered Harmful

© ACM, 1978-2009. This is the author's version of the work. It is posted here by permission of ACM for your personal use. Not for redistribution. The definitive version was published in ACM SIGPlan Notices, VOL#13, ISS#4, April 1978, pgs.76-79
(this work is available in ACM Digital Library

This mini-paper was written by myself and Bill Slater when we were both Graduate students at the University of Texas at Arlington in the mid-to-late 70's. We intended it purely as a spoof of the "X Considered Harmful" articles that seemed to be all the rage at that time. It was inspired by two articles in particular:

At the time, we felt good that we'd actually gotten ACM SIGPLan Notices to accept it (they accepted a lot of "informal" pieces like this back then) and it appeared appropriately in the April issue. We even inspired a couple of critical letters-to-the-editor in subsequent issues, although I concede that I solicited one of them from a colleague.

Imagine my delighted surprise when, while searching the Web for a copy, I discovered instead that our "paper" had been included/cited in no less than FOUR serious works. My particular thanks to Dick Grune of Vrije Universiteit in the Netherlands for this wonderful "citation" ...

(A)tongue-in-cheek paper which proposes various new crazy language structures that sometimes verge on the sane. Some of the more sane proposals are the COMEFROM statement, which emphasizes the fact that the state information from various points of departure of jumps must be merged at the point of arrival of the jump (R. Lawrence Clark, 1973); renaming REAL to RATIONAL, which indeed it is; and a comparison for almost equal, ' ~~ ', to be used to compare two reals for equality (which they almost never really equal anyway). One of the trivially insane proposals is the 'UNLESS (Boolean) DON'T for 'IF (Boolean) DO', if the Boolean is unlikely to be TRUE. Still, the example programs are almost readable, in a Cardassian kind of way. A view to another universe.

"..verge on the sane." I blush!

What is presented here is the original work with some minor updates (it's been 25 years since the original publication after all).


Structured Programming Considered Harmful

William Slater
Computer Science Department
University of Texas at Arlington
       Howard Modell
Computer Science Department
University of Texas at Arlington

It should be obvious that considerable attention has been lavished on improving the Programming Art by attempting to give it some discipline. This attention has produced control structures, like IF-THEN-ELSE, DO-WHILE, DO-UNTIL, SELECT-WHEN, and Co-routines, as well as new languages like PL/1, BLISS, PASCAL, EUCLID, and SL5 [1]. In addition, a set of techniques for the design and coding of programs has been proclaimed, called STRUCTURED PROGRAMMING." (SP)

One of the earliest tenets of SP was that the BRANCH control structure, epitomized by FORTRAN's GOTO statement, is inherently "dangerous". [2] This arose from the idea that unrestricted, undisciplined use of it leads to programs that are difficult, if not outright impossible to follow or debug. This, in turn, led to a deluge of articles expounding on the virtue of removing all GOTO's from one's program and replacing them with more advanced control structures.

We feel that the advocates of SP have gone a trible awry in their zeal. By saying that the traditional control structures and programming methods are obsolete or dangerous, and that the newer structures and methods are THE WAY to go, we feel that the advocates of SP are stifling the creative, artistic element in programming.

Therefore, we propose the following additional constructs which we feel will add new life, new gracefulness and new challenge (heh!) to programming.

First and foremost, we advocate replacing all GOTO's with COMEFROM's. [3] The semantics of "COMEFROM <label>" say that control continues with the statement following the COMEFROM immediately after executing the statement with the specified <label>. Variations on this statement include:

In the case of multiple COMEFROM's referring to the same label, the last executed COMEFROM would have precedence.

From STRUCTURED PROGRAMMING IN APL [4], we shamelessly plagerize the construct SKIP n, which says control passes to the nth statement following the SKIP.

To oppose this, we also offer a variety of REPEAT constructs:

REPEAT FROM <label>
passes control to the statement with the specified label;
REPEAT FROM <label1> TO <label2>
causes re-execution of the specified block of statements and then passes control to the statement following the REPEAT;
REPEAT FROM <label1> TO <label2> UNLESS boolean expression and
REPEAT FROM <label1> TO <label2> UNTIL boolean expression
conditional forms of REPEAT block;
REPEAT NEXT n and
REPEAT LAST n
causes the previous or the next n statements to be repeated. Control then passes to the statement following the REPEAT;
REPEAT NEXT n UNTIL boolean and
REPEAT NEXT n UNLESS boolean
conditional repeats (similarly, there are conditional REPEAT LAST statements);

Next, we present a variety of flexible IF statements. For example, the construct

IF boolean expression THEN block1
UNLESS boolean INWHICHCASE block2
ELSE block3
.

Then there are the triplets ...

...all of which randomly execute the action-block provided that the boolean expression is .TRUE./'1'b/non-zero (whatever the PL uses).

For the FORTRAN devotees whom we haven't already disgusted, we propose ...

IF (boolean) L1, L2, L3

which transfers control to the statement with label L1 if the boolean expression is .TRUE., to statement L2 if the boolean expr. is .FALSE., and to L3 if it is .MAYBE.

For new block control structures, we propose ...

We strongly suggest replacing the attribute/datatype REAL with the more sensible RATIONAL. Until computers with infinite word lengths become practical, it is confusing, not to mention erroneous, to talk about REAL data.

Further, it is suggested that DECLARE be made into an executable statement[5], or instead provide a REDECLARE statement. This is advocated in the knowledge that there will be times when a variable's attributes might not be decided upon until certain other data is computed or read-in. Also, there will be occasions when it is desireable to redefine a variables attributes at runtime while preserving hard-typing.

To enhance the flexibility of the basic assignment statement, we present [6]...

VAR ~= expression
/* un-assignment, which states that whatever value the variable VAR may have had before, it does not have the value of expression now. */
VAR ~=! expression
/* exemption, which says that VAR cannot EVER have had the value of expression */
VAR ~~ expression
/* approximation, which says that the value of VAR is approximately the value of expression. This is useful in processing RATIONAL data, where exact values are often improbable. */
VAR =! expression
/* Restriction, which states that VAR can ONLY have the value of expression */

The last construct is a general, all-inclusive EQUATE/DEFINED/EQUIVALENCE statement. We feel it should be permissible to perform the following equates ...

SQRT === **
/* function name equated to special symbol */
ADD === +
/* alternate symbol or operator */
3 === A
/* redefinition of a constant. Practical in FORTRAN [7] */
2 === 1
/* equivalence of constants */
+ === <function>
/* user-redefined operator */
* === X + 1
/* expression replaces symbol -- sort of MACRO expansion */

It is of interest that several of the above equates are already implemented in one language of another (SNOBOL4's OPSYM function, for example).

Just to show that these are indeed useful constructs, we conclude this article with several short sample programs.


(1)     COMEFROM BLARG;
        UNTIL (EOF) DON'T BEGIN;
             COUNT ~=! 0;
             AVERAGE = SUM / COUNT;
             PUT DATA (AVERAGE);
             STOP;
             END;
        GET LIST (X);
        COUNT = COUNT + 1;
 BLARG: SUM = SUM + X;
        END;

(2) GCD: Procedure (M,N) OPTIONS (RECURSIVE);
         DO UNLESS (M => N);  
             M <-> N;  /* <-> is an "Exchange" operator */
             N = M - N;
         DO UNLESS (N = 0);
             M = GCD (M, N);
         RETURN (M);
         END;

(3)      IF BOOL1 THEN DECLARE X RATIONAL
         UNLESS BOOL2
             INWHICHCASE DECLARE X CHAR(3);
         ELSE DECLARE X FIXED BIN(3);
             UNLESS BOOL3
                  INWHICHCASE DECLARE X BIT(1);

(4)      IF A=B THEN X = X + 1;
                UNLESS B>C
                    INWHICHCASE X = X - 1;
                ELSE X = 3;

References and Footnotes

  1. SL5, sort of a 2nd-generation SNOBOL, was succeeded by ICON. I suppose Perl, Python, and C++ ought to be added to the list as well.
  2. "Go To Statement Considered Harmful" by Edsger W. Dijkstra, CACM Vol.11, No.3, Mar.1968, pgs.147-148
  3. "A Linguistic Contribution to GOTOless Programming" by R.Lawrence Clark, DATAMATION Dec.1973, pgs. 62-63
  4. STRUCTURED PROGRAMMING IN APL, Dan Geller and Dan Freedman, Winthrop Publishers, Cambridge MA 1978
  5. it's scary to realize that there actually are now programming languages in which this is implemented.
  6. sadly, Perl and other modern PL's have pre-empted some of the glyphs we proposed.
  7. Most vendors plugged this hole eventually. Dang!