Software practicality.
In this paper, I try to introduce the concept of “practical practicality” and give it a more or less formal definition, but at the same time, in a simple, readable language.
First, the basic concepts used in the course of this article, and serve its purposes and only them. These concepts are valid and make sense only in the context of this article.
Tool.
')
A tool is a reusable, reusable code, usually a library, compiler, database, command line utility, framework, etc.
Tongue.
A language is a conceptual device used by a person using this tool. For example, the ls (or dir) command language is a set of words, in the first place where the words file and directory will be.
API
API is a program code that a user must type in order to access the capabilities provided by the tool.
BALL.
BAL is short for “basic algorithm,” for example, a quick sort algorithm, a binary tree. A certain function - around which the rest of the functionality of the tool is built. Or a set of such functions. As a rule, BAL has not a lot of code, but very complex, sometimes improved for dozens of years by academic scientists, professionals and hobbyists all over the world.
Glue.
The rest of the tool code provided by the API connects the BAL and the API. It is glue that usually makes up the bulk of the code in the tool. For example, in the mentioned ls command, BALLS are the functions readdir () and fstat (), they actually read files and directories. Everything else is glue, providing dozens of command line keys (API), output formatting (although, breaking the list of file names into columns is also, of course, BAL) and all the richness of the API and the language of this command.
So, practical practicality lies in the BAL-centricity.
Rule one: the glue should be as small as possible.
Ideally, there should be just enough glue to give the user access to the bals, no more and no less.
Rule two: the API should be as close as possible to the BAL interface on which this tool is built. Usually it happens the other way around, it is first thought up by the API, for solving its tasks, then BALs are searched based on which such a tool can be written, sometimes even one BAL is thrown out and another is put in place, keeping the API unchanged or modifying it minimally, usually because requires new parameters or functions.
For example, they wrote a certain container, API for it, and built it around the array, then it turned out that the linked list is better suited for the task, replaced the array with a linked list, but since the linked list provides the convenience of moving forward and backward, added functions next () / prev () which was not previously. It turns out that the API on the one hand is built on the basis of external considerations, the user's language, intended applications, and on the other hand, it depends on the internal structure of the instrument, primarily on the BAL used.
Rule three: BALLS must be high-end, that is, the best of what you can get.
This rule is the exact opposite of the frequently used approach, when the main efforts are spent on the development of glue, and there is no world class binary search, as a result, the BAL is written on the knee, adapted to the rest of the code. Because of its inefficiency, it cannot be used everywhere, and in those places where it does not fit, something else is being written. The main logic of the development is kept in the glue, and the BALs are attached from different sides in order to support this large object. Or GitHub is a world-class algorithm, but since it doesn’t fit the decisions already made in the tool, it doesn’t have to be wrapped or wrapped with wrappers. Instead of:
Rule number four: all code (or glue in the terminology of this article) should be balocentric. If an incompatibility of the BAL and your homebrew code is detected, the BAL is perceived as an arbitrator, as the highest authority, and the code is changed, so as to correspond to the features of the underlying algorithm used.
Rule Five: the language in which the users of the tool argue should include the basic principles of the basic algorithms. And at least everything else.
That is, instead of “phone”, “base”, “addresses”, “look in all” and so on, you not only provide the API by the key / value principle, but the user also has to reason in the same language that the basic algorithms are based on. For effective use of the basic algorithm is possible only within the framework of the conceptual apparatus of this basic algorithm. Simply put, if you, as a user, do not know what black-mahogany is, namely the tool you use is built on it, the tool will not be used effectively enough.
You can constantly observe the desire of programmers to hide the implementation details under the hood and give the person a steering wheel and a pedal. But along with the steering wheel and pedals, it is necessary to give him a language with the basic concepts of "clutch disc", "grip", "stopping distance". Ignoring the understanding of the device leads to accidents.
So, as a result, all activity in the development of the tool concentrates around the basic algorithms, the introduction of the best examples of such, or the development of their own unique ones. The work becomes much more technical and the conversations become more specific.
As a good example of software practicality, DB Redis can be cited.
Instead of the usual, more "convenient" abstract language, it gives the API where even the command names reflect the algorithms used: Set, List, Key / Value (Hash table). Although it was possible, according to principle 5, to call Skiplist ZList, because it is the algorithm that the ZList builds and the understanding of this fact by the user would make its application even more efficient. And there is nothing more there at all, there are BALLS, basic algorithms, and a set of functions for them.
You can even say this: if you have a client and he has tasks that are well solved by some basic algorithm, you must teach the client to speak the language of this algorithm, and not vice versa.
Practicality, this is not necessarily minimalism, especially when several BALS are connected in the tool and it becomes a serious task to provide the user with consistent access to all their capabilities at once. As in the same Redis, you can use Set and List in the same query. In such a case, the code connecting several BALs can itself become a complicated development and result in a new BALL. As, for example, LZ compression is two basic algorithms, search for repetitions using the sliding window method and Huffman compression, and it took a lot of work to connect these two algorithms to the third, which is now the standard BAL of multiple systems.
By the way, a good example, gzip is quite a tool in the spirit of practicality, it only gives minimal access to the gzip () function, unlike the pkzip utility, which has acquired a huge amount of functions. Of course, the comparison here is only partial, because pkzip has two key basic algorithms, compression and archiving of multiple files, and gzip is only compression.
There is another rule in minimalism: if there are rarely used features in your IPA, remove them. This is a completely different approach, and often it leads to its problems. The peculiarity of practicality is that you provide a complete set of functions associated with the basic algorithms.
If you are confused in the development of your own tool, try to shake everything out of it except the basic algorithms, and build anew on the principles of "balocentric" software practicality.
Practicality goes a little out of step with the world trend called modularity, which is usually voiced like this: “let the instrument do one thing and do it well”. Some similarities with the principles of practicality can be seen, but the starting point is different, practicality suggests starting from the basic algorithms themselves as they are, based on the fact that whatever you do, whatever functionality you implement, you will rely on the basic Algorithms in any case, you can not get away from them. Take them from open source, from Wikipedia, or create original ones, it is logical to build a system around them, than to constantly deal with them.
The author proposes to change the focus when developing systems, the most time-consuming and valuable code is the basic algorithms, but as a rule they are given very minor attention, instead of trying to put them at the forefront and build everything else around them.
Summarizing: less glue, advanced BALS, any conflict between them in favor of BALS, API and terminology are directly related to BALS.
The author of this article does not claim that such an approach to programming is the best, or better than others, that this is some kind of truth, it's just another approach that has proven itself with clear rules and conceptual apparatus.