
What does the program have between the lines

Knowledge of the rules of a chess game 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 try to illustrate with our own examples.
“- And what, comrades, is an idea?” An idea, comrades, is a human thought clothed in a logical chess form. Even with insignificant powers one can master the whole board. It all depends on each individual individual. For example, that blond in the third row. Suppose he plays well ... TheProgramming is like chess in the sense that knowing the "rules of the game" (a programming language, standard libraries) does not guarantee writing good code. This, alas, is obvious to anyone who has conducted 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 can have 10 years of the same type of writing experience in some forms (a chess player is hardly strong, having played the same game for 10 years in a row).
blond in the third row is red-hot.
“And that brunette, let’s say, is worse.”
Everyone turned and examined the brunette too.
“What do we see, comrades?” We see that the blond plays well and the brunette plays poorly. And no lectures will change this correlation of forces if each individual individually does not constantly train in checkers ... that is, I wanted to say - in chess ... “
I. Ilf, E. Petrov“ 12 chairs ”
But the maestro's words about the idea seem important to me. For a program, comrades, is a human thought embodied in the form of code. Accordingly, a quality code arises as a result of the embodiment of a quality thought (or, at least, at least some thought).
I am going to show with a simple example how to see this very thought behind the lines (or rather, between the lines) of the program and why such a “vision” helps to write high-quality programs. I will say right away - the described technique (primarily associated with the names of Dijkstra and Hoar) is decades old, and it, unfortunately, has not become the mainstream of programmer education. But the hope does not leave me that a couple more convincing and accessible examples - and the ice will break ...
A rare book on an introduction to programming does without the task of 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 Hanoi tower game is, and there will be only two teams in our programming language. So.
Given. Three pins (1, 2, 3) are depicted on a three-color screen, a ring is put on the first pin.

Black pins, gray ring, white background. Two commands are available:
Pin ( number , color )
Ring ( number , color )
Each command fills the corresponding rectangle with the corresponding color. For example, if you give the Ring (3, white) command in the described initial situation, the lower part of the right pin will disappear.
It is required to write a program, as a result of which the ring moves to the middle pin. Commands work instantly, no “animation effects” are possible and not required.
Try to write the desired fragment yourself. Too obvious? All the better.
This task was offered to people with very different degrees of training. Everyone coped, issuing one of three programs:
Solutions
A | 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 strong programmers wrote exclusively option A, were surprised when they were informed that there are other options, and could not explain why option A is better. Let's try to figure it out. To start, we’ll provide program A with comments:
// ring on pin 1
Ring (1, white)
Pin (1, black)
// all pins are empty
Ring (2, gray)
// ring on pin 2
In all comments we describe only the picture, obtained at the appropriate stage of execution, that is, not the actions of the program are commented on, but the state of the system before / after the relevant actions.
Why is program A good? She has a simple, symmetrical (with respect to the pin number) and natural (so it would be in reality) intermediate state. The state between the first and second teams (damaged 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 get out of this suspicious state and only then move on.
Okey, the patient reader will say, we respect the author’s beliefs, but what is the practical sense in all this besides abstract morality? Are Programs B and C worse in practice?
Let's take a closer look at program B, using the same trick - we will comment on the intermediate states of the system.
// ring on pin 1
Ring (2, gray)
// rings on pins 1 and 2 ???
Ring (1, white)
Pin (1, black)
As you can see, here we can describe the alleged intermediate state. And this description should instantly ignite an alarm for the developer - by the terms of the task, we have only one ring, not two. It would seem that for children's fears is software, as much as we want, we will draw as much. Why does an experienced programmer not choose this path? Perhaps because it saves mental effort - program A is “written off” from reality, that’s how we would rearrange the real ring on real pins. The consistency and feasibility of Plan A is, in a sense, guaranteed by nature, which saves on formal guarantees. Plan B suggests some kind of “virtual reality”, the consistency of which requires careful analysis. Two rings on adjacent pins - and they fit there? After such a question, the failed test for program B becomes apparent:

Program C operates in approximately the same order as A, only it delays the elimination of minor imperfections until 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 vice versa - in order to understand what is happening, one should keep in mind all three commands and the entire modifiable part of the picture. Perhaps an experienced programmer avoids this path again from saving mental effort - it’s better if we quickly solve all the problems with the starting pin and forget about them.
The practical problems with program C are less obvious than in case B. Imagine that later the customer of the program wished the possibility of transferring the ring from an arbitrary pin s (assuming that it is there) to an arbitrary pin d. We will need a modification of the original program (refactoring, yes). It seems like a natural idea to replace everywhere constant 1 with variable s and constant 2 with variable d. It turns out that program A can withstand such refactoring, but program C does not - it will not work correctly with s = d (check!).
Observation.Please note that choosing the right encoding option is much easier than understanding where the other options will break (unless of course we can read the program between the lines - either 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 the program so that the probability of error is minimal. Recall the saying about the resourceful and the wise: the resourceful knows how to get out of difficult situations, and the wise just do not get into them.
In conclusion, another version of the same program, demonstrating a certain divide between science and industry.
Ring (1, white)
Ring (2, white)
Ring (3, white)
Pin (1, white)
Pin (2, white)
Pin (3, white)
// solid white background
Pin (1, black)
Pin (2, black)
Pin (3, black)
// three empty pins
Ring (2, gray)
// ring on pin 2
Such a decision is hardly appropriate in a university course or in an interview, but it may be suitable in production. The author of the program honestly admitted that he was not able to calculate the correct “incremental change” and drew everything from scratch. Unlike the authors of programs B and C, he apparently managed to discern potential difficulties, but did not have the time or the ability to deal with them more effectively. It is useless to expect that in the near future there will be enough programmers writing ingenious code. But maybe we can at least teach most coders how to write “dumb” code like this?