Structural programming is a programming paradigm based on the representation of a program in the form of a hierarchical block structure. It was conceptualized in the late 1960s - early 1970s on the basis of the Böhm – Jakopini theorem , which mathematically substantiates the possibility of structural organization of programs, and the work of Edsger Dijkstra “On the Goto Operator’s Harm” .
In accordance with the paradigm, any program that is built without using the goto operator consists of three basic control structures: sequence, branch, loop; in addition, subroutines are used. At the same time, the program is being developed step by step, using the “top down” method.
The methodology of structured programming emerged as a consequence of the increasing complexity of the tasks solved on computers, and, accordingly, the complexity of the software. In the 1970s, the volume and complexity of programs reached such a level that traditional (unstructured) program development ceased to meet the needs of practice. The programs became too complex to be properly maintained. Therefore, systematization of the design process and program structure was required.
The methodology of structural software development was recognized as the “strongest formalization of the 70s”.
According to Bertrand Meier, “The revolution in thinking about programming started by Deakestroy led to a movement known as structured programming, which suggested a systematic, rational approach to the design of programs. Structural programming has become the basis for everything that has been done in programming methodology, including object programming ” [1] .
Content
History
Initially, the idea of structured programming came into being in connection with the goto operator and doubts about the expediency of its use. Heinz Zemanek expressed similar doubts for the first time at the Algol meeting in early 1959 in Copenhagen. However, this presentation did not attract attention and had no effect. Edsger Dijkstra recalls: “To some extent, I blame myself for not being able to appreciate the significance of this idea at that time” [2] [3] [4] .
The situation radically changed ten years later, when in March 1968 Dijkstra published his famous letter “Go To Operator Considered Harmful ” (Go To Statement Considered Harmful ). This is a truly historical document, which had a noticeable impact on the further development of programming.
The fate of the document itself is very interesting. The fact is that Dijkstra gave the article a completely different name: “A case against the GO TO operator” (A Case against the GO TO Statement).
However, at the time of publication, something incomprehensible happened - for some reason the article mysteriously turned into a “Letter to the Editor”, and the former title disappeared just as mysteriously. What really happened? Dijkstra explained the mysterious transformation of an article into a letter only many years later, in 2001, a year before his death.
Communications of the ACM magazine published my text entitled “GOTO Operator Considered Harmful.” In subsequent years, he was often quoted. Unfortunately, it was often done by people who saw in it no more than what was said in the title. This title has become the cornerstone of my fame ...
How did all this happen? I sent an article titled “Arguments against the operator GO TO”. To speed up the publication, the editor turned my article into a “Letter to the Editor”. At the same time, he came up with a new name for the article, which he invented himself. The editor was Niklaus Wirth [5] [6] .
Purpose
The goal of structured programming is to increase the productivity of programmers, including the development of large and complex software systems, reduce the number of errors, simplify debugging, modification and maintenance of software.
This goal was set in connection with the increasing complexity of programs and the inability of developers and managers of large software projects to cope with the problems that arose in 1960–1970 in connection with the development of software [7] .
Spaghetti Code
Structural programming is intended, in particular, to eliminate confusion and errors in programs caused by difficulties in reading the code, unsystematic, uncomfortable for perception and analysis of the source text of the program. Such text is often described as “ spaghetti code ”.
Spaghetti code is a poorly designed, poorly structured, entangled and difficult to understand program that contains many goto operators (especially transitions back), exceptions and other constructions that worsen the structuredness [8] . The most common anti-pattern programming.
Spaghetti code is so named because the flow of the program is like a bowl of spaghetti , that is, tortuous and tangled. Sometimes called “kangaroo code” ( kangaroo code ) because of the many jump instructions.
Currently, the term is applied not only to cases of goto abuse, but also to any “multiply connected” code in which the same small fragment is executed in a large number of different situations and performs many different logical functions [8] .
Spaghetti code can be debugged and work correctly and with high performance, but it is extremely difficult to maintain and develop [8] . Refinement of the spaghetti code to add new functionality sometimes carries significant potential for introducing new errors. For this reason, it becomes almost inevitable refactoring - the main cure for spaghetti.
Goto operator
Since the 1970s, the goto unconditional transition operator has been at the center of systematic and ever-increasing criticism. Wrong and thoughtless use of the goto statement in the source code of a program results in a confusing, unreadable “ spaghetti code ”. In the text of such a code, it is almost impossible to understand the order of execution and the interdependence of fragments.
For the first time, this view was reflected in the article by Edsger Dijkstra “The Go To Operator is Considered Harmful” [3] [9] . Dijkstra noted that the quality of the program code is inversely proportional to the number of goto operators in it. The article became widely known, as a result of which views on the use of the goto operator were significantly revised. In “Notes on Structured Programming” [10], Dijkstra justified the fact that for a code without goto, it is much easier to verify formal correctness .
The code with goto is difficult to format, since it can disrupt the hierarchy of execution (structured programming paradigm) and therefore indents designed to display the structure of the program can not always be set correctly. In addition, the goto operator interferes with the optimization by compilers of control structures [11] .
Some goto applications can create problems with the program execution logic:
- If a variable is initialized (gets a value) in one place and then used later, then going to a point after initialization, but before use, will result in the value that was in the memory allocated for the variable being selected before the moment of allocation (and which is usually arbitrary and random).
- Transferring control inside the loop body results in missing the loop initialization code or initial condition check.
- Similarly, the transfer of control inside a procedure or function results in the omission of its initial part, in which initialization is performed (memory allocation for local variables).
The arguments against the goto operator turned out to be so serious that in structured programming they began to regard it as extremely undesirable. This is reflected in the design of new programming languages. For example, goto is not allowed in Java and Ruby . In a number of modern languages, it is still left for reasons of efficiency in those rare cases where the use of goto is justified. So, the goto has been preserved in Ada - one of the most thoughtful in terms of architecture languages in the entire history [12] .
However, in high-level languages where this operator is preserved, there are, as a rule, strict restrictions on its use that prevent the use of the most dangerous methods of its application: for example, it is prohibited to transfer control from outside a loop, procedure or function inside. The C ++ standard prohibits variable initialization bypass with goto.
Structured Programming Theorem
The theorem was formulated and proved by the Italian mathematicians Corrado Boehm and Giuseppe Jacopini. They published it in 1965 in Italian and in 1966 in English [13] . Along with the theorem, the article by Böhm and Jakopini described the methods for transforming non-structural algorithms into structural algorithms using the example of the Böhm programming language P ′ ′ . P ′ ′ is the first Turing complete programming language without the goto operator.
The Böhm – Jakopini theorem is written in complex language and in unusual notation. If we use modern terminology and notation, it will look like:
Any program specified in the form of a flowchart can be represented using three control structures:
- the sequence is denoted: f THEN g,
- branching - denoted by: IF p THEN f ELSE g,
- cycle - denoted by: WHILE p DO f,
where f, g is a block diagram with one input and one output,
- p is a condition
- THEN, IF, ELSE, WHILE, DO - keywords [14] .
Explanation. Formula f THEN g means the following: first, program f is executed, then program g is executed.
As Harlan Mills points out, this theorem contrasts sharply with the usual (in 1960–1970) programming practice, when there was a massive use of goto transition operators [14] .
Boehm and Jacopini did not use the term "structured programming." Nevertheless, the theorem proved by them (and its subsequent variations by different authors) later became known as the “theorem on structured programming”, the “structural theorem” [14] , the “theorem on structuring” [15] .
Principles of structured programming
The formation and development of structured programming is associated with the name of Edsger Dijkstra [10] [16] .
Principle 1. It is necessary to abandon the use of the unconditional goto operator.
Principle 2. Any program is built from three basic control structures: sequence, branch, cycle.
- Sequence - a single execution of operations in the order in which they are written in the text of the program.
- Bertrand Meyer explains: "Serial connection: use the output of one element as an input to another, just as electronic engineers connect the output resistance to the input of a capacitor" [17] .
- A branch is a single execution of one of two or more operations, depending on the fulfillment of a given condition.
- Loop - multiple execution of the same operation as long as the specified condition is met (the condition of the continuation of the cycle).
Principle 3. In the program, basic control structures can be nested into each other in an arbitrary manner. No other means of controlling the sequence of operations is provided.
Principle 4. Repeating program fragments can be arranged in the form of subroutines (procedures and functions ). In the same way (in the form of subroutines) it is possible to design logically coherent fragments of the program, even if they are not repeated.
- In this case, in the text of the main program, instead of the fragment placed in the subprogram, the instruction “Subprogram call” is inserted. When executing such an instruction, the called subroutine works. After that, the execution of the main program continues, starting with the instruction following the “Subroutine call” command.
- Bertrand Meyer explains: “Transform an element, possibly with internal elements, into a subroutine characterized by one input and one output in the control flow ” [17] .
Principle 5. Each logically complete group of instructions should be arranged as a block . Blocks are the basis of structured programming.
- A block is a logically grouped part of the source code, for example, a set of instructions written in a row in the program source code. The term block means that the block of instructions should be referred to as a single instruction. Blocks serve to limit the scope of variables and functions. Blocks can be empty or nested inside one another. The boundaries of the block are strictly defined. For example, in an if statement, a block is limited to a
BEGIN..ENDcode (in Pascal), either curly braces {...} (in C) or indents (in Python).
Principle 6. All listed structures should have one input and one output.
- Arbitrary control structures (such as in a spaghetti dish) can have an arbitrary number of inputs and outputs. By limiting ourselves to controlling structures with one input and one output, we get the possibility of constructing arbitrary algorithms of any complexity using simple and reliable mechanisms [17] .
Principle 7. The development of the program is carried out step by step, using the top-down method [18] .
Top-down method
First, the text of the main program is written, in which, instead of each connected logical fragment of text, a subroutine call is inserted that will execute this fragment. Instead of the real working subroutines, fictitious parts are inserted into the program - stubs , which, to put it simply, do nothing.
More specifically, the stub satisfies the interface requirements of the fragment to be replaced (module), but does not fulfill its functions or partially fulfills them. Then the plugs are replaced or refined to these full-featured fragments (modules) in accordance with the programming plan. At each stage of the implementation process, an already created program should work correctly in relation to the lower level. The resulting program is checked and debugged [19] .
After the programmer is satisfied that the subroutines are called in the correct sequence (that is, the general structure of the program is correct), the stub subroutines are successively replaced with actual ones, and the development of each subroutine is carried out using the same method as the main program. Development ends when there are no stubs left.
Such a sequence ensures that at each stage of development the programmer simultaneously deals with the set of fragments that he can see and understand, and can be sure that the general structure of all higher levels of the program is correct.
When accompanying and making changes to the program, it becomes clear which procedures need to be changed. They are made without affecting parts of the program that are not directly related to them. This ensures that when making changes and correcting errors, some part of the program that is currently outside the attention of the programmer [18] [20] [21] [22] [23] [24] will not fail.
It should also be noted that in the “Preface” to the book “Structural Programming” [25] Tony Hoar notes that the principles of structured programming can equally be applied when developing programs from top to bottom and bottom to top [26] .
Subprogram
The subroutine is an important element of structured programming. Initially, subroutines appeared as a means of optimizing programs for the amount of memory they occupied - they made it possible not to repeat identical blocks of code in a program, but to describe them once and call them as necessary. By now, this function of the subroutines has become auxiliary, their main purpose is to structure the program for the convenience of its understanding and maintenance.
Selecting a set of actions into a subroutine and calling it as necessary allows you to logically select a holistic subtask that has a typical solution. This action has one more (besides memory saving) advantage over repeating actions of the same type. Any change (error correction, optimization, extension of functionality) made in the subroutine, is automatically reflected in all its calls, while during duplication each change must be made to each occurrence of the code being changed.
Even in cases where a set of actions produced once is allocated to a subroutine, this is justified, since it allows reducing the size of the entire code blocks that make up the program, that is, making the program more understandable and understandable.
The merits of structured programming
Following the principles of structured programming has made the texts of programs, even fairly large, normally readable. The understanding of programs has become much easier, it has become possible to develop programs in a normal industrial mode, when a program can be easily understood not only by its author, but also by other programmers. This allowed the development of sufficiently large for that time software systems by the forces of development teams, and accompanying these systems for many years, even in the face of unavoidable changes in the staff.
- Structural programming can significantly reduce the number of options for building a program for the same specification, which significantly reduces the complexity of the program and, more importantly, makes it easier for other developers to understand it.
- In structured programs, logically related operators are visually closer, and weakly connected ones are further, which allows you to do without flowcharts and other graphical forms of image algorithms (in fact, the program itself is its own flowchart).
- The process of testing and debugging structured programs is greatly simplified.
Clarity and readability of programs
Structural programming significantly improves the clarity and readability of programs [27] . Edward Jordan explains:
The behavior of many non-structural programs is often closer to the Brownian motion than to any organized process. Any attempt to read the listing leads a person to despair that in such a program several operators are usually executed, after which the control is transferred to a point a few pages below. A few more operators are executed there and control is again transferred to some random point. Here some more operators are being executed, etc. After several such broadcasts, the reader forgets how it all began. And loses the train of thought.
Structural programs, by contrast, tend to consistent organization and execution [28] .
The improvement of the readability of structural programs is explained by the fact that the absence of the goto operator allows you to read the program from top to bottom without gaps caused by control transfers. As a result, you can immediately (with one glance) find the conditions necessary for modifying a particular program fragment [29] .
Two-dimensional structured programming
The R-technology of program production, or “the technology of two-dimensional programming” [30] was created at the Institute of Cybernetics named after V. M. Glushkov [31] . The graphic system of the R-technology of programming is fixed in the standards of GOST 19.005-85 [32] , GOST R ISO / IEC 8631-94 [33] and the international standard ISO 8631N.
The author of the R-programming technology, Doctor of Physical and Mathematical Sciences, Professor Igor Velbitsky, suggested revising the very concept of “program structure”. In his opinion, “structure is a multidimensional concept. Therefore, the mapping of this concept with the help of linear texts (a sequence of operators) virtually nullifies the advantages of the structural approach. The enormous associative capabilities of the visual apparatus and the human thinking apparatus are used almost idly for recognition of structural images in the form of a uniform sequence of symbols ” [34] .
The methodology of two-dimensional structured programming differs significantly from the classical one-dimensional (textual) structured programming [35] [36] .
The ideas of structured programming were developed when computer graphics did not actually exist yet and the main tool of the algorithmist and programmer was a one-dimensional (linear or stepwise ) text. Before the advent of computer graphics, the methodology of classical structured programming was the best solution [10] .
With the advent of computer graphics, the situation has changed. Using expressive means of graphics, it became possible to modify, develop and supplement three types of basic (text) control structural structures, as well as completely abandon the keywords if , then, else, case , switch, break, while , do, repeat, until, for , foreach, continue, loop, exit, when, last, etc., and replace them with control graphics, that is, use two-dimensional structured programming [32] [35] .
An important problem is the complexity of modern programming and the search for ways to overcome it. According to the candidate of technical sciences, associate professor Evgeny Pyshkin, the study of structured programming solely as a tool for developing program texts based on the basic “structural triad” (linear sequence, branching and cycle) is insufficient and, in fact, negates the analysis of benefits. structural approach [37] . In the process of overcoming the essential complexity of software, the most important tool is the visualization of design and programming [37] .
See also
- Functional programming
- Logic programming
- Automated programming
- Procedural programming
- Object oriented programming
- Prototype programming
- Aspect-oriented programming
- Component-oriented programming
Notes
- ↑ Meyer B. Feel the class. Learning to program well with objects and contracts. - Per. from English - M .: National Open University INTUIT: BINOM. Laboratory of knowledge, 2011. - 775с. - p. 208. - ISBN 978-5-9963-0573-5
- ↑ E. Dijkstra. The goto operator is considered harmful.
- 2 1 2 Harmful Dijkstra E. Go To Statement Considered // Communications of the ACM, Volume 11, No. 3, March 1968, pp. 147–148. - Association for Computing Machinery, Inc.
- ↑ See also Dijkstra’s archive. EW Dijkstra Archive. The manuscripts of Edsger W. Dijkstra. - Department of Computer Science, University of Texas at Austin
- ↑ Manuscript EWD1308 from Dijkstra Archive. What led to "Notes on Structured Programming" - Nuenen, 10 June 2001. - Department of Computer Sciences. The University of Texas at Austin, USA
- ↑ Deciphering the manuscript EWD1308 from the Dijkstra Archive. What led to "Notes on Structured Programming" - Nuenen, 10 June 2001. - Department of Computer Sciences. The University of Texas at Austin, USA
- Linger, R., Mills, H., Whitt, B. Theory and practice of structured programming. - Per. from English - M .: Mir, 1982. - 406s. - p. 7.
- 2 1 2 3 John Vlissides, Kyle Brown, Gerard Meszaros AntiPatterns: The Survival Guide. Spaghetti code .
- ↑ E. Dijkstra. Go To is considered harmful.
- ↑ 1 2 3 Dijkstra E. Notes on structured programming. // Dal U., Dijkstra E., Hoor K. Structural programming. - M .: Mir, 1975. - P. 7–97.
- ↑ Donald Knuth. Structured Programming with go to Statements Archived May 19, 2013. 1974
- Complete Code Complete: A Practical Handbook of Software Construction Redmond: Microsoft Press, 1993. 880 p.
- ↑ Bohm, Corrado; and Giuseppe Jacopini. Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules (Eng.) // Communications of the ACM : journal. - 1966. - May ( vol. 9 , no. 5 ). - P. 366-371 . - DOI : 10.1145 / 355592.365646 .
- 2 1 2 3 Harlan D. Mills Mathematical Foundations for Structured Programming. - February 1972. - Federal Systems Division. IBM Corporaton. Gaithersburg, Maryland. p. four.
- ↑ Butakov E. A. Methods of creating high-quality computer software. - M .: Energoatomizdat, 1984. - 232s. - p. 114.
- ↑ Notes on Structured Programming. By prof. Dr. Edsger W. Dijkstra - TH Report 70-WSK-03 Second Edition April 1970.
- ↑ 1 2 3 Meier B. Feel the class. Learning to program well with objects and contracts. - Per. from English - M .: National Open University INTUIT: BINOM. Laboratory of knowledge, 2011. - 775с. - p. 209. - ISBN 978-5-9963-0573-5
- 2 1 2 Wirth N. Programming by Stepwise Refinement // Communications of the ACM, Volume 14, No. 4, April 1971, pp. 221–227. - Association for Computing Machinery, Inc.
- ↑ Glass R. Reliable Programming Guide. - M .: Finance and Statistics, 1982. - 256s. - p. 84.
- ↑ Hughes J., Michtom J. Structural approach to programming. - M .: Mir, 1980. - 278c. - pp. 29-71. (See “Chapter 2. Downstream development. Program design” and “Chapter 3. Downstream development. Planning and implementation”).
- ↑ Wirth N. Systematic programming. Introduction - M .: Mir, 1977. - 184s. - p. 139-168. (See “Chapter 15. Step-by-Step Program Development”) .
- ↑ Glass R. Reliable Programming Guide. - M .: Finance and Statistics, 1982. - 256s. - pp. 83-87. (See Section "3.3.1. Programming from top to bottom and bottom to top").
- Linger, R., Mills, H., Whitt, B. Theory and practice of structured programming. - M .: Mir, 1982. - 406s. - p. 324-327. (See Section "7.3.3. Structural Programming on the Top-Down Principle" and "Section 7.3.4. Programming Using the Principle of Step-by-Step Reorganization").
- ↑ Ivanova G. S., Nichushkina T. N. Software design. A manual for the implementation and registration of course, degree and qualification works. - M .: Moscow State Technical University. N. E. Bauman. Faculty of Informatics and Control Systems, 2002. - 74s. - pp. 28-31.
- ↑ Dal U., Dijkstra E., Hoor K. Structural programming. - M .: Mir, 1975. - 247c.
- ↑ Hoor K. Preface. // Dal. W., Dijkstra E., Hoor K. - M .: Mir, 1975. - 247c. - p. 6.
- ↑ Yodan E. Structural design and design of programs. - Per. from English - M .: Mir, 1979. - 415s. - p. 174.
- ↑ Yodan E. Structural design and design of programs. - Per. from English - M .: Mir, 1979. - 415s. - p. 174, 175.
- ↑ Yodan E. Structural design and design of programs. - Per. from English - M .: Mir, 1979. - 415s. - p. 175.
- ↑ Velbitsky I.V., Khodakovsky V.N., Sholmov L.I. Technological complex for the production of programs on EC computers and BESM-6 machines. - M .: Statistics, 1980. - 263s. - p. 5.
- ↑ Stogny A. A. Preface. // Velbitsky I.V., Khodakovsky V.N., Sholmov L.I. Technological complex for the production of programs on EC computers and BESM-6 machines. - M .: Statistics, 1980. - 263s. - p. 3.
- ↑ 1 2 Interstate standard GOST 19.005-85. Unified software documentation system. R-schemes of algorithms and programs. Symbols conditional graphic and rules of execution. Unified system for program documentation. R-charts. Graphical chart symbols and conventions for charting. 1985.
- ↑ GOST R ISO / IEC 8631-94 Information technology. Software constructs and conventions for their presentation. Information technology. Program constructs and conventions for their representation. State Standard of Russia. - Publishing Standards, 1995.
- ↑ Meet R-technology // NTR: problems and solutions. - 1987, No. 13, July 7-20. - p. 4, 5.
- ↑ 1 2 Ermakov I.Ye., Zhigunenko N.A. Two-dimensional structured programming; class of directed graphs. (Theoretical research from the experience of the language "DRAGON") . - M .: Moscow State University. M. V. Lomonosov, 2010. - P. 452—461. - (Collection of works of the V International Conference "Innovative information and educational technologies in the IT education system"). (inaccessible link)
- ↑ Shamardina EI, Manyunin P. А. The language of algorithmic drawings “DRAGON”, its mathematical model and editor // New information technologies. Abstracts of the XVII International Student Conference-School-Seminar. - M .: MIEM, 2009. - 399s. - p. 279, 280. - ISBN 978-5-94506-223-8
- ↑ 1 2 Pyshkin, 2005 , p. ten.
Literature
- E. Pyshkin. Structural Design: The Basis and Development of Methods. With examples in C ++: Textbook. allowance . - SPb. : Polytechnic University, 2005. - 324 p. - ISBN 5-7422-1000-0