Knowledge of the rules of a chess game still does not make a person a grandmaster, knowledge of a programming language does not make a person a programmer. And what is lacking in both cases? We are looking for answers to both questions from recognized masters and trying to illustrate with our own examples.
“- And what is this, comrades, does an idea mean? The idea, comrades, is a human thought, clothed with logical chess form. Even with insignificant forces, you can master the whole board. It all depends on each individual. For example, that blond in the third row. Suppose he plays well ...
The blond in the third row blushed.
- And that brunet over there, let's say, worse.
They all turned and looked at the brunet as well.
- What do we see, comrades? We see that the blonde plays well, and the brunette plays badly. And no lectures will change this correlation of forces if each individual will not constantly train in a hat ... that is, I would like to say - in chess ... “
I.Ilf, E.Petrov “12 chairs”
Programming is like chess in the sense that knowledge of the “rules of the game” (programming language, standard libraries) does not guarantee writing good code. This, alas, is obvious to anyone who has spent at least a couple of dozen interviews on a programming position. The Testament of the Great Combinator (education is nothing, the main experience) does not always work - a person may have 10 years of the same type of writing some kind of forms (a chess player is hardly strong, having played the same game for 10 years in a row).
But the words of the maestro about the idea seem to me important. For the program, comrades, is a human thought embodied in the form of a code. Accordingly, a quality code arises as a result of the implementation of a quality thought (or, at least, at least some thought).
I'm going to show with a simple example how to see this very idea behind the lines (or, rather, between the lines) of a program and why such a “vision” helps to write quality programs. I will say right away - the described technique (associated primarily with the names of Dijkstra and Hoare) for decades, and, unfortunately, it never became the “mainstream” of programmer education. But hope does not leave me, that a couple more convincing and accessible examples - and the ice will break ...
')
A rare book on introducing programming does without the task of the Hanoi towers. Now we will encode a completely “side” fragment of such a program. We don’t even need to know what the “full version” of the game of towers of Hanoi consists of, and in our programming language there will be only two teams. So.
Given. Three pins (1, 2, 3) are shown on the three-color screen; a ring is worn on the first pin.
The pins are black, the ring is gray, the background is white. Two commands are available:
Pin (
number ,
color )
Ring (
number ,
color )
Each team fills the corresponding rectangle with the corresponding color. For example, if you give the command Ring (3, white) in the described initial situation, then the bottom part of the right pin will disappear.
It is required to write a program, as a result of which the ring will move to the middle pin. Commands work instantly, no “animation effects” are possible and are not required.
Try to write the necessary fragment yourself. Too obvious? All the better.
This task was offered to people with very different degrees of training. All coped, giving one of three programs:
SolutionsA | B | C |
Ring (1, white) Pin (1, black) Ring (2, gray)
| Ring (2, gray) Ring (1, white) Pin (1, black)
| Ring (1, white) Ring (2, gray) Pin (1, black)
|
In a random audience decisions A, B, C were issued with approximately equal probability. But the strong programmers wrote only option A, were surprised when they were informed that there were other options, and could not explain what option A is better. Let's try to figure it out. To begin with, we will provide program A with comments:
// ring on pin 1Ring (1, white)
Pin (1, black)
// all pins are emptyRing (2, gray)
// ring on pin 2In all comments, we describe only the image obtained at the appropriate stage of execution, that is, it is
not the program's
actions that are commented on, but the system
state before / after the corresponding actions.
What is good program A? It has a simple, symmetrical (with respect to the pin number) and a natural (so it would be in reality) intermediate state. The state between the first and second teams (spoiled first pin) does not have a simple description and does not correspond to reality. Perhaps this is why an experienced programmer intuitively seeks to first leave this suspicious state and only then move on.
Okekey, the patient reader will say, we respect the author’s beliefs, but what is the practical meaning of all this, apart from abstract morality? Are programs B and C worse in practice?
Let's take a closer look at program B using the same technique - we will comment on the intermediate states of the system.
// ring on pin 1Ring (2, gray)
// rings on pins 1 and 2 ???Ring (1, white)
Pin (1, black)
As you can see, and here you can describe the estimated intermediate state. And this description should instantly ignite an alarming signal for the developer - by the condition of the problem we have only one ring, not two. It would seem that for children's fears - this software, as we want, draw so much. Why an experienced programmer does not choose this path? Perhaps because it saves mental effort - program A is “written off” from reality, this is how we would rearrange the real ring on real pins. The consistency and feasibility of plan A is in some sense guaranteed by nature, which saves on formal guarantees. Plan B assumes a certain “virtual reality”, the consistency of which requires careful analysis. Two rings on adjacent pins - and they fit there? After such a question, the failure test for program B becomes obvious:

Program C operates in approximately the same order as A, only it postpones the elimination of minor defects for later. There is no understandable intermediate state in it, as a result of which the reader's attention constantly jumps from the first pin to the second and back - to understand what is happening, you should keep in mind all three commands and the entire modified part of the picture at the same time. Perhaps an experienced programmer avoids this path again, because of mental savings - it’s better that we quickly solve all the problems with the start pin and forget about them.
Practical problems with program C are less obvious than in case B. Imagine that the customer of the program later wished to transfer the ring from an arbitrary pin s (assuming it was there) to an arbitrary pin d. We will need to modify the original program (refactoring, yes). A natural idea seems to replace everywhere constant 1 with variable s and constant 2 with variable d. It turns out that program A maintains such refactoring perfectly, but program C does not - it will not work correctly with s = d (check!).
Observation Please note that choosing the right coding option is significantly easier than understanding where the other options will break (if we, of course, can read the program between the lines, consciously or intuitively). In our opinion, a programmer's qualification primarily consists not in the ability to understand where the error is in the program, but in the ability to write a program so that the probability of an error is minimal. Recall the saying about the resourceful and wise: the resourceful is able to extricate himself from difficult situations, and the wise simply do not get into them.
In conclusion, another version of the same program, demonstrating a watershed between science and industry.
Ring (1, white)
Ring (2, white)
Ring (3, white)
Pin (1, white)
Pin (2, white)
Pin (3, white)
// solid white backgroundPin (1, black)
Pin (2, black)
Pin (3, black)
// three empty pinsRing (2, gray)
// ring on pin 2Such a decision is hardly appropriate in a university course or an interview, but it may be suitable in production. The author of the program honestly admitted that he could not calculate the correct “incremental change” and drew everything from scratch. Unlike the authors of programs B and C, he apparently was able to discern potential difficulties, but did not have the time or the ability to cope with them more effectively. It is useless to expect that in the near future there will be enough programmers writing a brilliant code. But maybe we can at least teach most coders to write “stupid” code like this?