Most of us had excellent grades in school and university math. Remember how we solved the examples? Let's say you need to take the derivative of a function:

We thought for a few seconds and recorded the finished result:

Pupils wrote down the solution step by step and spent significantly more time:
')

We, excellence, all this to nothing. Why write so many unnecessary intermediate actions when you can immediately ready answer? We want to get rid of this example as soon as possible to go on to the next one!
Why can we, and others can not?
Mathematics and short-term memory
No, it is obvious that we can perform all the necessary operations in the mind, and we do not need to write down intermediate results on paper. But why is this possible?
In cognitive psychology, that part of memory in which calculations are made directly “in the mind,” is called short-term and working. Everything is complicated and ambiguous, but whatever you call it, and the amount of this memory is very limited. Various researchers call "magic numbers" seven and five. These are average values. The amount of "working" memory depends on the circumstances and correlates with intellectual abilities.
It turns out that the ability not to record intermediate results is due to the capabilities of our working (or short-term) memory. We, the techies, have a working memory for storing “technical” elements that is larger than that of the humanities. The more memory, the more intermediate steps we can accumulate in it without recording.
Programming and short-term memory
And now let's try to imagine how our supernormal abilities work when we program.
To solve the resulting problem, you need to write a certain amount of code. But we are in a hurry, and we are able to keep in mind a lot of details. Feel where I'm going? We do not record intermediate steps. Instead, we write such algorithms that get the original data and immediately give the finished result. They are long, these algorithms, and they do a lot of work. As much as we could fit in our own working memory when they were written.
Hypothesis. The smarter the programmer (the more extensive working memory he has), the longer methods and functions he writes.
Let's try to calculate how much a large amount of working memory is required when programming. Since we do not know how exactly thinking is arranged, and with which “objects” it operates, we will simply count the independent objects that are found in the program code.
As a test subject, I took
a 150-line Ruby function from the
BigBlueButton project. I admit at once that this code has touched me to the quick. I had to spend a couple of days and almost completely rewrite several methods to make cosmetic changes to the functionality of a small part of the project. No longer string of lines of any kind could be reused.
This code perfectly illustrates the hypothesis. It was written just as we used to solve examples. The mass of intermediate steps was kept directly in the head, and only the final decision fell on paper. 150 lines that solve the whole damn problem in one fell swoop. This code was clearly written by a very talented guy!
We do this not maliciously. The basis of the programmer’s work is to keep in mind a huge number of objects and connections between them. What is wrong with the fact that we will immediately use more of these objects in one method in order to get rid of them as soon as possible and move on to the next large set of objects? Consistent solution of the problem "little by little", "step by step" - this is for troechnik, right?
So, I roughly
counted the number of independent objects that appear in the code. The number of objects that had to be kept in the head more or less at the same time in order to understand what is happening in this whole rates from top to bottom. Here's what I got:
- 4 function arguments, which are mentioned a total of 15 times;
- 42 internal variables used 131 more times;
- 52 references to 24 different elements of the hashes passed to the function as arguments (to work with the code, you must keep in mind the internal "structure" of all these hashes);
- 9 calls to 8 different external entities (constants and methods of classes).
Total, counting to a minimum, turned out 4 + 42 + 24 + 8 = 78 independent objects. And I have not yet considered the operations that are performed on objects. But the operation also "occupy" some share of working memory.
78 objects against the "magic" seven - is it a bit too much for one function?
Of course, here you can endlessly argue that once the code is written and works, it means that 78 objects are not a problem at all. This is not the longest method, is it? Means, objects can be even more? Besides, who said that all 78 must be kept strictly at the same time?
The problem of the long method is not that it is impossible to understand. The problem is that it is difficult to understand it, because it requires efforts to “warm up our cache.” It takes time and effort to load into the working memory the entire set of objects that make up the studied code fragment, and keep them there for a long time. The more objects - the more apply working memory, but it is different for everyone, and the same developer depends on the degree of fatigue and mood ...
Metrics and short-term memory
Various metrics are used to assess the quality of the code. For example, Maurice Halsted
researched numerical code metrics back in the 70s (!) Years. It seems to be clear that measuring and evaluating the quality of the code is a good thing. And there is no doubt that the more complex the code, the more mental effort it requires. But there is one question with metrics. As
EvgeniyRyzhkov puts it , “the main thing in the metrics is not to
figure out what to do with them.”
Programming is a complex intellectual process. Its course is influenced by many factors. The most significant factor, in my opinion, is the properties and limitations of the main working tool for creating code - the programmer's intelligence. The study of the "internal structure" of intelligence is engaged in cognitive psychology. Thanks to her, it is reliably known that the capabilities of the intellect are limited, and the magnitude of these limitations has even been measured. And once the capabilities of the instrument are limited, it means that the “product” will and must have certain specificity. "Will" - because the code is the product of the brain-tool. “Must” - because the code is at the same time also the raw material.
The raw code must meet certain criteria so that the brain tool does not break during its processing.
Since the science that studies the properties of intelligence is called cognitive, then it is also logical to call the metric, which corresponds to the limitations of this intelligence, cognitive. I will name it, say,
cognitive weight . And then the
cognitive complexity is already
taken . By the way, Halstead, in his Beginnings of the Science of Programs, describes a metric to which cognitive weight is very similar. Only Halstead does not appeal to the concept of "cognitive". (By the way, Cognitive Psycology R. Solso was first published in 1979, and Elements of Software Science M. Halstead - in 1977).
So, I answer the question about metrics.
Practically useful code quality metrics should be built so that they show which code the brain will work with easily, and on which it will “break”. And not “intuitively”, but based on data obtained from cognitive science.
Summary
Recording a step-by-step solution is not only required so that the trio can solve an example. It is necessary that reading and verification of the solution require so little mental effort that even a troechnik could do it. An excellent student will understand the solution record without intermediate steps, but if the examples are complex and thousands need to be read ... In general, you understand.
Next time I will talk about the techniques that I use to reduce the complexity of my code.
PS One of my shaitan-methods, which the hands cannot refactor, has a length of 120 lines. Cognitive weight even did not want to count. Shame on you
UPD
Judging by kamentah, I vaguely expressed the meaning that I put into the terms “high school student” and “troechnik”. This pair of terms is just a literary device: metaphor and hyperbole. Some short names were needed for the concepts of “a person with abilities to the exact sciences above the average” and “a person with less developed abilities to the exact sciences”. Nowhere in the text, as it seems to me, I do not praise the first and discredit the second. On the contrary, one of the ideas “wired” in the text (not new and not mine): if the “honors pupils” use their excellent abilities in the coding process thoughtlessly, nothing excellent will come of it.
School grades for me have never been an indicator of something substantial. I myself had very average grades in all subjects except mathematics. I always tried my daughter to instill the idea that evaluation is not the most important thing in life. It is important that something be in your head: knowledge, understanding, interest in something. Although she did not listen to me and finished school with a gold medal.
UPD2
No, I had in mind precisely those excellent students who understand and understand, and not bison. In training subjects, our abilities allow us to get the right decisions very quickly, skipping non-essential intermediate steps. And in real technical problems, a high solution speed, as a rule, is a positive factor.
And in programming, intermediate steps are suddenly the most significant. And we are starting to genuinely wonder about the raids on our beautiful 300-line functions. But we did try, we did the best we can do! Nobody just explained that programming needs exactly the opposite:
writing stupid code , and quick and smart solutions always have harmful consequences.
I was told at the university only about Dijkstra’s structured programming, and I learned about the principle of sole responsibility much later. What is surprising that I talked about the length of the method, relying on someone's advice about the size of the screen, not understanding what the real reason why the methods should be short.