Staple, an experimental structured programming language

Staple, an experimental structured programming language

ComputerLanguages,Vol.I, pp. 61-71. Pergamon Press, 1975.Printedin NorthernIreland STAPLE, AN EXPERIMENTAL STRUCTURED PROGRAMMING LANGUAGE S.L. STEWA...

706KB Sizes 0 Downloads 130 Views

ComputerLanguages,Vol.I, pp. 61-71. Pergamon Press, 1975.Printedin NorthernIreland

STAPLE, AN EXPERIMENTAL STRUCTURED PROGRAMMING LANGUAGE S.L. STEWART Institute for Computer Science and Technology, National Bureau of Standards, Washington, DC 20234, U.S.A. (Received 2 November 1973 and in revisedform 5 February 1974)

Abstract--STAPLE is a structured programming language with nested block structure in the source language to indicate flow of control. The semanticsof the non-control structures are essentiallythe same as FORTRAN. The design goals were an easily implemented, easily modified tool for experiments and demonstrations of structured versus unstructured programming techniques. Structured programming Quality software Language design Block structure Control flows Precompiler GOTO-lessprograms 1. INTRODUCTION STAPLE is a language for experimentation in structured programming; it is a labelless, procedural language utilizing F O R T R A N syntax and semantics for the non-control statements and with new control structures to replace the GOTO, IF, and DO statements of FORTRAN. The design goals were to make a language and implementation which would: (1) clearly demonstrate the principles of structured programming, (2) be easy to implement, (3) be easy to modify for future experimentation, and (4) run on a wide variety of computer systems, so that others could perform similar experiments. Questions of implementation or object code efficiency were secondary, as were other aspects of programming languages not related to control structures. There are many problems with languages which influence software quality, but this project concentrated on flow of control. The description of the STAPLE language in this paper strives to be implementation independent, but a few facts about the original implementation may motivate some explanations. Design goal four suggests that STAPLE should be implemented as a precompiler which is written in, and compiles into, some widely used programming language. Such an approach also facilitates goals two and three, and it provides the natural opportunity to bootstrap the entire operation. Since two of the claims for structured programming are that it is easy to write and modify, bootstrapping is attractive as a test of these claims as well as the system. COBOL and F O R T R A N immediately suggest themselves as being widely used with reasonably standard subsets. Neither language has recursion or much provision for coroutines or parallel operation, but none of these is required to demonstrate the principles of structured programming. By adhering to certain restrictions it is possible to write structured procedure divisions in COBOL without "goto's". In F O R T R A N it is impossible to write nontrivial programs without statement labels, and therefore it is a monumental task to show that all the "goto's" in a program are good "goto's", i.e. well structured. One conclusion is that a structured language built on F O R T R A N would show most clearly the differences between structured and conventional programming. 61

62

S . L . STEWART

F O R T R A N was chosen as the language for the initial implementation and as well as the target language for the precompiler. The precompiler is written in very nearly ANSI Standard F O R T R A N [1]; the major exception is the use of the apostrophe as a string quote in order to avoid deep syntactic analysis for the "nil" convention. Non-control statements are passed with little or no analysis to the output code, so that whatever is acceptable to the local F O R T R A N compiler may be used in STAPLE programs. Every effort was made to change FORTRAN as little as possible beyond eliminating all use of statement numbers and adding the necessary control structures. In particular, the temptation to improve F O R T R A N in ways unrelated to control structure was resisted in order to avoid ambiguity in future experimental results. The following description assumes a knowledge of FORTRAN syntax and semantics. Additional STAPLE syntax is described informally and with modified Backus-Naur (BNF) rules [2]. Some of the syntactic classes are assumed to be self-explanatory. The original implementation of STAPLE subsumes these rules, therefore they should be taken prescriptively rather than restrictively, e.g. a semicolon at the end of a statement which is not required by the rules may be allowed by the precompiler. Furthermore, some erroneous but interpretable constructs are flagged without stopping the precompilation. The advisability of these and similar variations is one of the subjects for experimentation with this system. 2. P R O G R A M

UNITS

A STAPLE program unit is a string of characters recognized by the precompiler as complete and sufficient. It must be a block with a beginhead. In order for the translation of a STAPLE program unit to be a FORTRAN program unit, the statements within the block must satisfy FORTRAN requirements as well. The various FORTRAN requirements will be assumed to be satisfied from here on and will not be mentioned except where clarity requires. A block is a sequence of statements, separated by semicolons, preceded by a blockhead, and followed by a blockend. The statements, in turn, can be blocks or simple statements. Generally, simple statements correspond to the allowable FORTRAN statements. In BNF: (program unit) : : = (block) (block) : : = (blockhead) {(statement);}* (statement) (blockend) (statement): : = (condition): (statement) I(block)l (simple statement) A condition can be any F O R T R A N logical expression. The effect at execution of a statement preceded by a condition is that the statement is executed if and only if the condition is true. Side effects due to testing the condition are determined by the local FORTRAN compiler; the original STAPLE implementation compiles conditions into "IF (.NOT. (condition)) GOTO label". Naturally a statement with a condition is called a conditional statement. 3. B L O C K S

In this version of STAPLE there are three kinds of blocks corresponding to three kinds of control structures. The three control structures chosen are: sequencing, looping,

STAPLE, an experimental structured programming language

63

and branching. These three structures, given a suitable definition, are sufficient [3, 4]. Because it is impossible to conform to all p r o g r a m m i n g language traditions simultaneously, the final choice for the exact semantics of the three block types is somewhat arbitrary, and the choice of tokens, or keywords, to signify the block type is completely arbitrary. Block type is distinguished by the first part of the blockhead. Sequencing starts with B E G I N , looping starts with R E P E A T , and branching starts with SELECT. (block): : = (blockhead){ (statement) ;}* (statement) (blockend) (blockhead): : = B E G I N \ ( t a g ) I R E P E A T \ ( t a g ) I SELECT\(tag) (blockend): : = E N D \ ( t a g ) Terms like beginblock, beginhead, etc. take on their natural meaning. (tag) is any sequence of letters and digits followed by a blank or semicolon with a practical limit on length determined by the implementation. Tags longer than the patience of programmers are easy to allow. Tags are not necessary to structured programming, BEGIN\NEWTON.RAPHSON.ONE REAL X1,X,Y1 ,Y,DYI ,DY,EPS; INTEGER LIMIT,KOUNT; DATA LIMIT,EPS[I 5,1.0E-6/; ~oTHIS IS A NEWTON-RAPHSON NON-LINEAR EQUATION SOLVER TO DEMONSTRATE THE FEATURES OF THE STAPLE STRUCTURED PROGRAMMING LANGUAGE~o REPEAT\LOOP READ(5,PROMPT='NEW STARTING VALUE=')X;FI0.0; X .LT. -- 10000.0:EXIT; X1 =X; CALL SUBR(XI,Y1,DY1); KOUNT = 1 ; ABS(Y1) .GE. EPS: REPEAT\IMPROVE DY1 .EQ. 0: BEGIN\FLAT DY1 =1.0; WRITE(6) :' LOCAL FLAT'; END\FLAT; X=X1--Y1/DY1 ; CALL SUBR(X,Y,DY); KOUNT = KOUNT + 1 ; ABS(Y) .LT. EPS:EXIT; SELECT\TEST ABS(Y) .LT. ABS(Y1): BEGIN\REPLACE Xl =X; Y1 =Y; DY1 =DY END\REPLACE: DY1 =DYI*2.0 END\TEST; KOUNT .GT. LIMIT:EXIT' END/IMPROVE; KOUNT .GT. LIMIT:WRITE(6):' MAX ITERATION'; WRITE(6)X, KOUNT:' ROOT=',G15.7, ITERATIONS=',14; END\LOOP; STOP END\NEWTON.RAPHSON.ONE Fig. 1. This is an example of a program written in STAPLE. All three block types, conditional assignments, calls, input-output, termination, and declarations are used. The "prompt" in the READ statement shows the use of non-standard FORTRAN features where they do not interfere with the definition of STAPLE.

64

S.L. STEWART

but they are included on an experimental basis for two purposes. First, it gives the programmer an opportunity to document the intended function of the block with a meaningful tag, and second, it gives the precompiler a check on proper nesting of blocks. This is achieved by requiring the tag on an END to match the tag on the corresponding blockhead. More stringently, the tag is required to be unique in the current nest of tags. It would be possible to require each tag in a program unit to be unique, but this does not seem advisable on the basis of current experience. Not only does a tag match the head and end of a block for the precompiler; it does the same for anyone who reads the program. In most block structured languages, the concept of block is intimately related to the scope of variables and definitions, a subject of great interest to programming language designers. Because of the experimental nature of STAPLE, the block structure is used only for its control structure aspect. STAPLE inherits FORTRAN's scope rules for reasons (2) and (4) in the Introduction.

Nesting

3.1.

Blockheads and blockends enforce a nesting discipline in the same way as parentheses do in arithmetic expressions. In fact, an earlier version of STAPLE used parentheses since there is no syntactic ambiguity and single characters are easy to check. The result was parenthesis glut, familiar to every LISP programmer. The current syntax for blockheads and blockends is derived from the form made well known by ALGOL60 and widely copied. It is expected that this syntax will continue to be a subject for debate and experimentation. The level of nesting of any statement is the number of blocks which contain that statement, and the current block of a statement is the block which immediately contains the statement.

Beginblocks

3.2.

The BNF for a beginblock is derived from that for a block in general given above. (beginblock): : = BEGIN \ (tag){statement) ;}* (statement) END\(tag) where the tags are identical. The execution sequence for a begin block is from BEGIN to END and on to the statement following the blockend if this is not the outermost block. Every statement at the current level in the block is executed unless the statement is conditional and the condition is false when evaluated during execution. The form of the other block types is the same but the sequence of execution is different. 3.3.

Repeatblocks Repeatblocks have a BNF of: (repeatblock): :=REPEAT\(tag){(statement) ;}* (statement) END\(tag)

where the tags are identical. The sequence of execution is the same as for beginblocks with two exceptions. First if an EXIT statement (see termination statements §4,5) is executed at the current level, control is transferred to the point immediately following the blockend. Second if execution

STAPLE, an experimentalstructured programminglanguage

65

reaches the blockend without executing an EXIT at the current level, control is returned to the blockhead. Thus a loop is set in operation until an EXIT is reached. It is required that every repeat block have at least one EXIT at the current level, but there may be as many EXITs as the programmer wants. Normally the EXIT will be part of a conditional statement that tests for a termination condition. Looping or its equivalent, e.g. recursion, is necessary for any general programming language, but it also opens the possibility for a program to be nonterminating. This possibility is a very annoying fact of life for a professional programmer, because an error on his part may turn a correct and terminating program into a nonterminating one. Structured programming isolates the possibility of nontermination in the looping structures, and in the case of STAPLE there is only one looping structure, the repeatblock. In this way the programmer knows where to be careful and where to check, when an endless loop is encountered during testing. Also, this restriction makes automated checking of programs easier and simplifies the problem of proof of correctness. Clearly, one function of the repeatblock is to replace the DO-loop of FORTRAN or the for-loop of ALGOL60, but there is no index variable. If a variable is needed for this purpose, it is a simple matter to initialize it before the repeathead, increment (or decrement) anywhere in the repeatblock, and include the variable in the exit condition. The increase in flexibility over the FORTRAN restrictions on index variables should more than make up for a few keystrokes. There is also some question of the utility of index variables. Much of the rationale behind their introduction was to implement vector and matrix operations, sorting, and searching. In higher level languages, these operations can generally be handled more efficiently by operations which are primitive to the language, thus eliminating this need for index variables. Unfortunately FORTRAN lacks these primitives, at least partly because there is no facility for dynamic storage allocation. However, it is outside the scope of the STAPLE to cope with this problem, and no need was felt to perpetuate index variables as a distinct entity at this time. This is another possible subject for experimentation. Repeatblocks in STAPLE differ from the more widely used looping constructs in allowing multiple exits and exits from the middle of loops. Three practical arguments in favor of this construct are: it is very convenient for the programmer, it is a trivial syntactic extension, and it is easy to implement. The idea was suggested by the omega-structures of Bohm and Jacopini [3] and was motivated by the discussion in Knuth and Floyd [5]. The theoretical justification is handled in detail by Kosaraju [4]. 3.4. Selectblocks As before, the BNF for selectblocks is: (selectblock): : = SELECT\(tag) {(statement);}* (statement) END\(tag) where the tags are identical. The sequence of execution is the same as for beginblocks except for the sequel to execution of a conditional statement at the current level. If a conditional statement at the current level is encountered during execution, the condition is evaluated as usual. If the condition is true the corresponding statement is executed. If this statement is conditional the process of evaluation is done as before. IfaU the conditions are true, then the innermost statement is executed and control is transferred to the statement beyond the selectblock. If

66

S.L. STEWART

a condition is false, control is transferred to the next statement following the conditional statement at the current level, as in beginblocks. Selectblock is a generalized n-way branching construct, patterned after the LISP cond-expression. Commonly there is a sequence of "condition:statement" pairs, where conditions are evaluated until the first true condition is found, and the corresponding statement is executed. If no true condition is found, then no statement is executed. The general form of selectblock in only slightly more complex. If there is more than one condition e.g. "I.EQ.J:I .EQ. K: D(I)= 1.0 ;", the effect is an AND of the conditions with the evaluation stopping on the first false condition. Only if an conditions are true does control transfer to the end of the selectblock, after executing the statement. The other semantic question is the interpretation of unconditional statements. These statements are executed as they would be in a beginblock if execution reaches them. At the end of a selectblock, unconditional statements serve the function of an else-construct. In the middle of a selectblock, that is before the last conditional statement, the best interpretation for an unconditional statement is yet another subject for experiment and debate. Selectblock includes the 2-way branch, or if-then-else construct, found in many programming languages and articles on structured programming; why not just use it? The 2-way branch is sufficient and convenient for proving theorems about flow of control in programming languages, but there is nothing special about 2-way branches, as opposed to all others, in actual programming. A programmer may remember that any n-way branch can be constructed from (n -- 1) 2-way branches, but in STAPLE there is no reason to limit him in that way. It is also true that the conditional statement, already introduced, with repeatblocks and beginblocks, is logically sufficient. But the conditional statement was introduced, in part, as a shorthand for selectblocks with one condition. An important experimental possibility is the utility of other such shorthands. There are several other variations of the branching construct which have been tried in other languages and in earlier versions of STAPLE. These include: the computed branch in which statement i of n statements is executed, the equality branch in which a given expression is tested for equality against a sequence of expressions and the first (or all) statement corresponding to a true test is executed, and additional provisions for or-if and or-else. Other variations are easy to imagine, but the present course is to implement one, simple yet general form and to experiment from there. 4. STATEMENTS The original definition of statement, given above was: (statement): : ~ (condition): (statement) 1(block) J (simple statement) Blocks were explained in the previous section, and conditions were defined in terms of FORTRAN logical expressions and their effect explained in the previous section. It remains to consider simple statements. In general, simple statements are the usual, non-control statements of FORTRAN both executable and non-executable. When written in STAPLE the most obvious difference is the ALGOL60-1ike use of semicolons. Because STAPLE is free form with only cosmetic line orientation, the semicolon is used as a statement separator, and continuation is automatic in the absence of a semicolon or blockend. Of course, there are no statement numbers nor are there any FORTRAN statements which require statement numbers in their syntax.

STAPLE, an experimental structured programming language

67

The syntax for the simple statement is: (simple statement): : = (non-executable) [(assignment)l (subroutine call)I(input-output)l (termination) (termination): :=STOP I R E T U R N [ E X I T 4.1. Non-executable Non-executable statements are the same as in F O R T R A N with the exception of F O R M A T , which is not included. Formats are treated under input-output statements below. Non-executable statements include: (1) (2) (3) (4)

Specification statements Data initialization statements Function defining statements Subprogram statements.

4.2. Assignment Assignment statements in STAPLE are the same as arithmetic and logical assignment statements in FORTRAN. Naturally, the ASSIGN-label statement is not included because it requires a label. 4.3. Subroutine call Subroutine calls in STAPLE are the same as in FORTRAN. Again, the reminder that statement numbers as actual parameters would be nonsense and, because the original implementation does not check such things, even dangerous. 4.4. Input-output Unformatted F O R T R A N input-output statements are acceptable to STAPLE as is. Formatted input-output uses the F O R T R A N statements, " R E A D (unit n u m b e r . . . " and " W R I T E (unit n u m b e r . . . " with modifications. First, the format statement number and its antecedent comma are omitted. Second, the input-output list is followed by a colon. And third, the format specification follows the colon. The format specification does not start with the word F O R M A T and need not include the outermost parenthesis pair. The format specification is followed by a semicolon or a blockend. Input-output has always been a major stumbling block in programming language design. The first objective of the STAPLE input-output statement design was to eliminate the format statement number for consistency, but to do it in such a way that implementation was as easy as possible and minimum violence was done to F O R T R A N syntax. The use of colon as a separator causes no ambiguity so long as READ and WRITE are not used as initial names in a condition. This solution does not facilitate the use of one format with several input-output statements, but that practice itself violates the spirit of structured programming by making the text harder to read and debug. 4.5. Termination Three simple statements, two from F O R T R A N and one addition, are needed to complete the fiow of control. These statements present unusual conceptual problems because even though they are trivial to implement they are part of the control structure. The

68

S.L. STEWART

decisions about the preferred meaning of these, or similar, statements determines in large part the choice of control structures and vice-versa. The BNF for the three termination statements is simple: (termination):: =STOP] RETURN] EXIT The use of STOP and RETURN is the same as in FORTRAN, and the use of EXIT was given in the section on repeatblocks. In one sense, all three are very similar--STOP transfers control out of the current program and back to the system if there is one, RETURN transfers control out of the current subprogram and back to its calling subprogram determined by dynamic nesting, i.e. the nesting imposed by execution, and EXIT transfers control out of the current repeatblock determined by static nesting, i.e. the nesting in the source text. There is a general requirement that every program have a STOP, every subprogram have a RETURN, and every repeatblock have an EXIT. The last is enforced by STAPLE. Another requirement enforced by STAPLE is that if a termination occurs, it must occur at the outermost level. That is, STOP and RETURN must be at level 1, and EXIT must be at the current level of its repeatblock. It is easy to relax these restrictions in the implementation, but such relaxation is the kind of experimentation STAPLE was designed for. Wulf discusses various approaches to this problem in the design of BLISS [6]. 5. COMMENTS AND HOLLERITH STRINGS Comments may be included anywhere within the program string except in keywords, blockheads, or blockends. The form of a comment is a character string which starts and ends with a per cent sign and includes no other per cent signs. (comment)::----~/o(any string not containing a per cent)~o The precompiler scans from left to right through the program string and starts processing a comment upon reaching the first per cent sign which is not part of a Hollerith string. It is not recommended that comments be inserted in the middle of statements, but programmer taste is so variable on the placement and form of comments that the actual restrictions were minimized. The major exception to ANSI Standard FORTRAN [1] is in the definition of Hollerith string. STAPLE will accept the standard "nil" form if the string contains none of the characters syntactically significant to the precompiler. In that case the string is passed on without being recognized. But STAPLE uses the widely accepted convention of a single string quote, i.e. apostrophe, as a string delimiter. The definitions of Hollerith strings and comments are similar, with the role of single string quote and per cent sign reversed. A contiguous pair of single string quotes (not a ditto) in a Hollerith string represents one single string quote. If the STAPLE Hollerith string is used, the corresponding facility and definition are assumed in the local FORTRAN compiler. STAPLE makes no changes in the character sequence in either comments or Hollerith strings. (Hollerith string): :='(any string not containing an unpaired single string quote)' 6. CONCLUSIONS The original implementation of this version of STAPLE has been running for almost a year on the General Services Administration's time sharing service, Infonet. During that time several thousand lines of source code have been written in STAPLE, primarily by the

STAPLE, an experimentalstructured programminglanguage

69

author and summer student employees. The largest single program thus far is the precompiler itself which is about 500 lines long. It was hand translated to FORTRAN originally but has been maintained in STAPLE ever since. The other programs have been experimental in nature comparing structured versus unstructured styles, ease of constructing programs, and particular problems that have been discussed with respect to structured programming, e.g. searching and backtracking. Quantitative results of these experiments will be reported in the future, but a few statistics about STAPLE, as implemented, can be given. The FORTRAN intermediate code for the precompiler has been easily and successfully transferred to three other machines, two large and one mini. In this case, transferability probably owes more to the care spent in avoiding implementation dependent characteristics of FORTRAN than it does to structuring, but the structure did not interfere with this goal. Measures of program size are somewhat arbitrary. One of the side-effects of this precompiler is to produce a neatened listing of the source program with a new, suitably indented line for each blockhead, blockend, and simple statement. Using the number of lines in that listing as the measure of STAPLE program size and the number of FORTRAN statements as a measure of intermediate code size, the change in code size has been between zero and a 20 per cent increase. This counts numerous superfluous CONTINUE statements in the intermediate code. Subjectively, the experience of working with a structured language has been very favorable, especially when modifying code either to correct a bug or meet revised specifications. The current trend is toward more program development from remote terminals using text editors and on-line files instead of keypunches and cards. To take full advantage of this trend, languages and software support should match this mode of operation as closely as possible; certainly label-free, nested block structure is one step in this direction. The advantages claimed for structured programming by Dijkstra [7], Wulf et al. [6], and others have generally been born out with respect to control flow for the class of problems typically programmed in FORTRAN. However, two potential problems for structured programming have received sufficient attention in the literature to deserve special comment; these are multi-level exits and node splitting, see for example Knuth and Floyd [5] or Peterson et al. [8]. Multi-level exiting is the facility to transfer execution out of more than just the current level of nesting, in particular to exit more than one level of loop nesting. This means that an inner block with exits to two different levels is a one-in, many-out block in its control flow, rather than a one-in, one-out block structure. STAPLE was designed to allow only one level of exit in order to assess the practical difficulty of such a restriction. Except for the widely known cases of nested search procedures and error recovery, the experience has been that the biggest need is for an exit-after-the followingcomputation construct. This is an easily implemented construct which does not involve multi-level exits from looping structures. Node splitting is the process of copying a piece of code or a box in a flow chart in order to produce an equivalent program or flow chart which satisfies some structure constraints. It is known that some unstructured programs can be rewritten in structured form by replicaing parts of the code. Note that node splitting increases the size of the source code but does not change execution sequence, hence the running time should be the same, or better if linear code runs faster than branched code. The question is: if the programmer is restricted to a narrow definition of allowable structure, as in STAPLE, how often will identical pieces of code need to appear in the program. Thus far the incidence of node splitting has not

70

S.L. STEWART

been very high. There are two statements, X1 = X, in Fig. 1 which are the residue of a node split, but in general more has been gained through seeing the node splits clearly, analyzing their origin, and sometimes making a fundamental improvement in the code. In FORTRAN, even with a single programmer, it is easy to write equivalent code in several isolated places without recognizing that a common function is being performed. Future plans include, (1) continued experimentation with the influence of control flow structure on programming, (2) a limited extension of certain constructs in STAPLE based on past experience, and (3) some syntactic modifications to accommodate more human factors. The next major problem will be the relationship of data references and scope of variables to the control flow structure. SUMMARY Widespread recent interest in the source language structure of programs has led to several important theoretical results with implications for the practical problem of producing quality software on a cost effective basis. To test the effects of structure requirements on programming, an experimental language, STAPLE, was designed and implemented. It is a block structured language with flow of control entering only at the beginning and leaving only at the end of each block, i.e. one-in, one-out blocks. There are syntactically recognizable blocks for branching (SELECT) and looping (REPEAT). Looping is terminated by a conditional EXIT construct as suggested by Knuth and Floyd. The language was designed to a rather narrow definition of structured programming so that experiments with the language would quickly bring out practical problems. A second goal was to be able to make comparisons with programs in an unrestricted language. The result was a language which preserved the syntax and semantics of FORTRAN except for flow of control. STAPLE has been implemented as a one-pass precompiler into FORTRAN, and the precompiler itself is maintained in STAPLE. Originally it was bootstrapped by hand translation from STAPLE to FORTRAN, about 500 lines of code. This method of implementation was not only easy but also resulted in portable, easy to modify code. For example, the language has been transfered to two other large systems and one small computer by means of the FORTRAN intermediate code produced by precompiler applied to its own source code. At the same time modifiability facilitates experiments with control structure semantics. Initial experience with the language on small numerical and semi-numerical problems of the type commonly done in FORTRAN has not revealed any unusual difficulties due to the structure restrictions. Programming seems to go faster with fewer incorrectly programmed branches, but final judgement must await the quantifiable experiments for which STAPLE was designed. Acknowledgements--I wouldlike to thank the other staffmembers of the ComputerSciencesSectionat NBS for all the open-ended discussions during the development of STAPLE. Tony Horowitz, a 1972 BIBS academic summer employee, not only contributed to the discussion, but also implemented one earlier version and designedanother.

REFERENCES 1. American Standard FORTRAN, ASA X3.9-1966. American National Standards Ass'n; New York (1966). 2. P. Naur (Ed.), Revisedreport on the algorithmiclanguageALGOL 60, Communs Ass. comput. Mach. 6, 1-17 (1963). 3. C. B~hmand G. Jacopini,Flowdiagrams,Turingmachinesand languageswithonlytwo formationrules, Communs Ass. comflut. Mach. 9, 366-371 (1966).

STAPLE, an experimental structured programming language

71

4. S. R. Kosaraju, Analysis of Structured Programs, Tech. Rep. The Johns Hopkins University (1972). 5. D. E. Knuth and R. W. Floyd, Notes on avoiding 'Go To' statements, Inf. Proc. Letters 1, 23-31 (1971). 6. W.A. Wulf, D. B. Russell and A. N. Habermann, BLISS: a language for systems programming, Communs Ass. comput. Mach. 14, 780-790 (1971). 7. E.W. Dijkstra, Notes on Structured programming, Structured Programming, pp. 1-82. Academic Press, New York (1972). 8. W. W. Peterson, T. Kasami and N. Tokura On the capabilities of while, repeat, and exit statements, Communs Ass. comput. Mach. 16, 503-512 (1973).