Programming Philosophy 7 - Practicism

    Software Practicism.

    In this paper, I try to introduce the concept of “program practicality” into circulation, and give it a more or less formal definition, but at the same time in a simple readable language.

    First, the basic concepts used throughout this article, and serving its purposes and only them. These concepts are valid and make sense only in the context of this article.

    Tool.

    A tool is reusable, reusable code, usually a library, compiler, database, command line utility, framework, etc.

    Tongue.

    Language is a conceptual apparatus used by a person using this tool. For example, the language of the ls (or dir) command is a set of words, in the first place in which will be the words file and directory.

    IPA.

    API is a program code that a user must type in order to access the capabilities provided by the tool.

    BALL.

    BAL is an abbreviation for “basic algorithm”, for example, quick sort algorithm, binary tree. A certain function - around which the rest of the tool’s functionality is built. Or a set of such functions. As a rule, BAL does not have a lot of code, but it is very complex, sometimes improved for decades by academic scientists, professionals and hobbyists around the world.

    Glue.

    The rest of the tool code that the API provides provides 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 aforementioned ls command, BALS are the readdir () and fstat () functions, they actually read files and directories. Everything else is glue, which provides dozens of command line keys (API), formatting of the output (although splitting the list of file names into columns is also, of course, BAL) and all the richness of API and the language of this command.

    So, program practicality is BAL centricity.

    Rule one: glue should be as small as possible.

    Ideally, the glue should be exactly enough to provide the user with access to the BALS, no more and no less.

    Rule two: API should be as close as possible to the BAL interface on which this tool is built. Usually it’s the other way around, first an IPA is invented to solve its problems, then BALs are searched for on the basis of which such a tool can be written, sometimes one BAL is thrown out and another one is thrown in its place, keeping the IPA unchanged or minimizing it, usually because the new BAL is simply requires new parameters or functions.

    For example, they wrote a certain container, for it API, and built it around an 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, we added the functions next () / prev () which were not previously. It turns out that the IPA, on the one hand, is built on the basis of external considerations, the user's language, the intended applications, and, on the other hand, depends on the internal structure of the instrument, primarily on the BALs used.

    Rule Three: BALS must be high-end, that is, the best of what you can get.

    This rule is the exact opposite of the often used approach, when the main effort is spent on developing glue, but there is no binary search for, say, a very effective, world-class time, as a result, it is written on the BAL knee and adjusted to fit the rest of the code. Due to its inefficiency, it cannot be used everywhere, and in those places where it does not fit, something else is written. The main logic of development is held in glue, and BALs are attached from different sides to support this colossus. Or a world-class algorithm is taken from GitHub, but since it is not ideal for the decisions already made in the tool, it is finished off or weighted by wrappers. Instead of:

    Rule Four: All code (or glue in the terminology of this article) must be balocentric. If the incompatibility of the BAL and your homegrown code is detected, the BAL is perceived as an arbiter, as the highest authority, and the code is changed so as to correspond to the particularities of the underlying algorithm.

    Rule fifth: the language in which the users of the tool reason must include the basic principles of basic algorithms. And, a minimum of everything else.

    That is, instead of “phone”, “base”, “addresses”, “look in all” and so on, you not only provide APIs on a key / value basis, but the user must also reason in the same language in which the basic algorithms are built. For the 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 a black-red tree is, and it is the tool that you use is built on it, then the tool will not be used efficiently 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 pedal. But along with the steering wheel and pedals, you need to give him a language with the basic concepts of "clutch disc", "grip", "braking distance". Ignoring the understanding of the device leads to an accident.

    So, as a result, all the activity in the development of the tool is concentrated around basic algorithms, introducing the best examples of those, or developing your own unique ones. Work becomes much more technical and conversations become more specific.

    A good example of software practicality is DB Redis.

    Instead of the usual, more “convenient” abstract language, it gives APIs where even the names of the commands reflect the algorithms used: Set, List, Key / Value (Hash table). Although it was possible according to principle 5, ZList was called Skiplist because, precisely, the ZList is built on the skiplist algorithm and understanding of this fact by the user would make its application even more effective. And there is nothing more at all there, there are BALs, basic algorithms, and a set of functions for them.

    You can even say this: if you have a client and it has tasks that are well solved by some basic algorithm, you should teach the client to speak the language of this algorithm, and not vice versa.

    Practicalism is not necessarily minimalism, especially when several BALs are connected in an instrument and it becomes a serious task to provide the user with consistent access to all of their capabilities at once. As in the same Redis, you can use Set and List in the same query. In this case, the code connecting several BALs can become a difficult development in itself and result in a new BAL. For example, LZ compression is two basic algorithms, sliding window search repetition and Huffman compression, and it took a lot of work to combine these two algorithms into the third, which is now the standard BAL of many 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 overgrown with a huge number 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 only compression.

    There is another rule in minimalism: if your API has rarely used features, remove them. This is a completely different approach, and often it leads to its problems. The peculiarity of practicality is precisely in the fact that you provide a complete set of functions associated with basic algorithms.

    If you are confused in developing your own tool, try to shake everything except the basic algorithms out of it and reassemble it according to the principles of "balocentric" software practicalism.

    Practicalism is not keeping pace with the global trend called modularity, which is usually voiced as follows: "let the instrument do one thing and do it well." Some similarities with the principles of practicalism 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 anyway, no matter what you do, whatever functionality you implement, you will rely on basic algorithms in any case, you can’t get away from them. Take them from open source, from Wikipedia, or create original ones, it’s logical to build a system around them, than constantly fight them.

    The author suggests changing the focus when developing systems, the most time-consuming and valuable code is the basic algorithms, but as a rule they are given very secondary attention, instead of trying to put them at the forefront and build everything else around them.

    Summarizing: less glue, promote BALs, any conflict between them in favor of BALs, IPAs 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 established itself with clear rules and a conceptual framework.

    Also popular now: