
It is considered that the comprehensibility of the code is a thing, firstly, a subjective thing, and, secondly, it is not quantitatively measured. There are various quantitative code metrics, but there is no intelligibility metric among them. To machine to measure the clarity of the code, you need its semantic analysis, and this is the task of artificial intelligence.
But let's look at the problem from the other side. What do we do when we deal with someone's code? How is the process of learning the code? We scroll through functions, look for definitions of variables, classes, move from function to function, from file to file.
')
The last two tasks that I performed at work were related to analyzing someone else's code and issuing recommendations for improving / rewriting it. All I did was to switch from file to file, go over classes, functions, and variables, trying to understand their purpose.
From this was born the idea of how to quantify the clarity of the code. The point is very simple: you need to measure the number of transitions and scrolls and normalize them by the number of lines of code. If we evaluate the clarity of the function, then we will normalize by the number of lines in the function. Similarly for the class, and for the whole project. According to this assessment, the ideal would be a code that is enough to scroll down once. Or, in the limiting case, it will suffice to scroll through only one main function. The program code should be similar to plain text, which is read linearly from top to bottom once.
Here are some offhand examples that will help you understand the essence of this metric:
Example 1 : you see a variable in the code with a name that doesn’t say anything (for example, j). You will find the definition of this variable (make the transition), and, if lucky, there will be a comment explaining what it means. If you are unlucky and there is no comment, you will have to look for all the places where it is used (to make transitions) and try to understand its purpose. And even if there was a comment on the variable, you will probably soon forget it, and you will have to return to it again (to make the transition).
Example 2 : in the code, you encountered a function call with a name that doesn’t say anything. Moreover, it is not clear what the function can produce. You will have to make the transition to the implementation of this function, repeatedly rewind it up and down to understand what it does and what result it returns. And if the function turns out to be 200-300 lines long, then there will be a lot of scrolling.
Example 3 : in the analyzed function there is multiple nesting: conditions in cycles, cycles in conditions. Keeping in memory is very difficult, and you will periodically scroll up to keep the entire context in memory.
Example 4 : logically related functions are randomly scattered around a file or are in other files altogether. And in order to find the implementation of the called function, one has to scroll, switch, switch, losing the current context of consideration from memory.
Example 5 (not from real work, hypothetical): If we are too keen on refactoring, we will separate every elementary action into a function / class, then navigating through them can also exceed all reasonable limits. The comprehensibility of the code will also fall, since there will be a lot to keep in memory.
Thus, the metric includes an assessment of:
- names of variables, functions, classes
- function sizes
- nesting
- the sequence of functions in the file
- redundant comments that reduce the amount of useful code on the page
- using patterns,
that is, many of the code quality criteria written about in refactoring articles and books.
I foresee the question that this method of assessing clarity is not without subjectivity. I agree. I see two main difficulties here.
First, someone is used to frequently navigating through code, and someone is able to keep context in memory. But still this method is more objective than just an assessment based on opinion. And, given the simplicity of the implementation of such an assessment, it would be interesting to see the result.
And secondly, at first, developers can intentionally less (more) scroll through the code to get the desired rating. But when such a check becomes a familiar practice in the organization, it is likely that the fraud will disappear.
I want to make a reservation right away that the proposed method allows to evaluate only the clarity of the code (including the quality of the interfaces), but not the quality of the architecture, the absence of duplication, dependencies, etc. That is, it makes sense to use it in combination with other metrics and code analyzers.
It can be implemented as a plug-in for IDE.