Reflections on programming

    From Aristotle to Wittgenstein


    I do not need a language that allows you to create good programs. I am looking for a language in which it is impossible to write a bad program. Author

    Foreword

    The development of computer science as a science seems to be a river that is born in the distant past (Euclid, III century BC; Babylon, XIX century BC; and possibly earlier) from barely noticeable streams of the first algorithmic calculations. Moving slowly through history, streams unite into a river, which, carrying its waters through the ages, absorbs tributaries from related disciplines, accumulates majesty and power, and finally breaks down Niagara Falls from the second to the third millennium, turning into a rapid raging stream, which it captures and carries millions of people from the past to the future.



    The Brownian particle, which is then thrown on a rapids with turbulent current, then it is thrown into a stagnant swamp, then in shallow water, then into a whirlpool; the world of information technology is seen as mysterious, volatile and unpredictable. However, the joy of constant movement, the heroic overcoming of difficulties, the frantic rotation of a kaleidoscope of new impressions with time is replaced by longing, yearning of spirit and an irresistible need to rise above the bustle for a moment, look from the side at this frantically bubbling stream and try to discern, if not the general direction of the stormy river, then at least the nearest turn of the duct in which you are floundering.

    Introduction

    “If a scientist cannot popularly explain to an eight-year-old child what he is doing, then he is a charlatan”
    Kurt Vonnegut, “Cradle for a Cat”, 1963

    A. “There is no silver bullet,” F. Brooks saidback in the last century and for a long time cooled the ardor of noble knights from programming in the fight against the "Dragon of Complexity". Since then, “His Majesty the Dragon” has served as an excuse that instead of some poorly working programs, users are imposed more and more, which are not much better, but are devouring more and more processor resources and computer memory (“What? People are hitting!” ( c) B. Titamir). In order to please the Dragon, a whole army of programmers like “code & fix” (“do and remake”) has been grown: “Not with skill, but with a number!”, “Refactoring is our everything!”, “Even members of the Republican Party can program!” their banners. To feed the Dragon, they create gigabytes of source code every day, much of which will never be claimed by users. Over the years, this disgusting Dragon has grown and become an “Idea. Historical necessity. Our state interest. A powerful factor, a justification for our combined efforts. ”

    B. We are not going to look for another “silver bullet”, but not because it does not exist, but because, no matter how you would like, it is difficult to believe in dragons. Dragons, as a rule, are born in the minds of people when they encounter phenomena that cannot be explained in their previous experience. For computer science, the presence of white spots is not surprising because it is a very young branch of human knowledge.



    Q. Few programmers believe in dragons, but many believe that complexity is a subjective concept. One of the definitions of the word “complex” is difficult, confusing. For example, a difficult task, a complex (or, more precisely, a confusing?) Program. What is difficult and confusing for one person can be easy and clear for another. The motion of the planets in the geocentric Ptolemy model of cycles and epicycles, as amended to them, looks complicated. The motion in the heliocentric model according to Kepler ellipses is simple. If you edit images in a bit format, it will be difficult, but if in a graphics editor, then simply. The image of the Mandelbrot set can be mesmerized by the complexity of the uninitiated observer, but in an adequate language the Mandelbrot set is described very simply: “the set of points with on the complex plane,0 = 0, z n = z n-1 2 + c ( n = 1, 2, 3, ...) does not go to infinity. "

    G. There is nothing difficult and confusing in nature. Something can only seem difficult and confusing to the person who is trying to understand something. Maybe the software systems that we develop we ourselves make complicated and confusing? Why is there more than 50 thousand tables in the SAP / R3 ERP system, and only about 54 thousand nouns in the largest Russian language dictionary? Sometimes, I regret to feel like a charlatan, trying to explain to the customer why it is so difficult to add the simple functionality that he asks for to the program.

    D. In this post I do not set any tasks for myself, except for one thing - to write down my not very connected, but sometimes incomplete thoughts about the most common programming issues that I have been thinking about over the past twenty years. Time is inexorable and it may simply not be enough for me in order to collect all the necessary “stones” and build from them a sufficiently strong foundation for the new programming paradigm. I will be satisfied if my thoughts turn out to be useful to someone, and, perhaps, will push some of my colleagues to go in search of the missing “stones”.

    Abstracts


    “Every task becomes trivial if formulated in an adequate language ” I.M. Gelfand

    About programs

    Program = task + model + algorithm + data structure

    The program is created in order to solve a specific problem: provide spacecraft control during the flight to Phobos, recognize the offender from a photograph in a stream of people, receive an SMS message from one mobile phone and transfer it to another.

    The model describes what the program should do to solve the task, but not how it should do it. The (mental) models of the domain created in human thinking can relate to both real-world phenomena, for example, the movement of a space object in the gravitational field and the Earth’s atmosphere, and ideal concepts, such as an online store. A model is a mental image of a future tool that will allow us to solve the task.

    The key concept in defining a program is task. As it is unreasonable to discuss a technical system in isolation from the task that it solves, it makes no sense to consider a program outside the goals for which it is being created. To solve different problems, even in the same subject area, different models will be created and different programs will be developed. To calculate the trajectories of interplanetary flights, it is enough to simulate the gravitational field as a superposition of the point masses of the Sun and planets. For practically acceptable accuracy of predicting the motion of satellites in near-Earth orbits in the gravity model, it is necessary to take into account the inhomogeneity of the Earth's field in the form of an expansion in harmonic functions or a specially selected system of point masses. And the solution of certain tasks of the global satellite navigation system (GLONASS / GPS) is impossible without the involvement of models of time and space from the General theory of relativity.

    So, a program is a solution written in a language understandable to some calculator that is facing us.



    About the Object Oriented Approach

    Today, about 2500 programming languages ​​are created for recording programs. The history of their development is somewhat similar to the history of the development of human speech. There is an opinion that the content of the first utterances of a person consisted solely of the requirements of the help that another individual could provide him. “If the first statements of a becoming person were expressed with the help of our developed language, they would necessarily contain verbs in the imperative mood:“ give ! ”,“ Carry ! ”,“ Break ! ”,“ Cut ! ”,“ Beat ! ”,“ lift ! ”,“ pull! ” etc.". Moreover, these commands were accompanied by gestures that accurately indicated what exactly this action should be applied to. Well, very similar to commands of imperative programming languages! For example, assembler commands with exact indication of memory addresses or registers.

    A person first learns to distinguish one practical situation, taken as a whole, from another situation. Separation of the individual elements of these situations (objects over which actions are performed, actions that are performed over objects) is carried out later - as in practical activity a person more and more gets acquainted with things surrounding him, learns about their properties and their relationship to each other and to to the person himself. Gradually, a person begins to isolate an object of action from a specific situation (in programming, data) and the action itself (in programming, functions). The mastery of the ability to distinguish objects of action was a real revolution in the mental development of primitive man. And this is already very similar to the object-oriented approach (OOP) used in programming. At least in its modern implementation in languages: C ++,

    Using natural language, a person materializes his mental models of the world in order to transfer them to another person. Using OOP, a programmer materializes his mental models of a software product in order to transfer them to a calculator for execution. But is OOP really the main channel of our river? Or is it just a quiet backwater before a sharp turn, which is characterized by a slow and sometimes reverse flow of water and which has already begun to swamp?

    The use of OOP to build mental models of the physical world has more than two thousand years of history of successful use, which originates in the writings of Aristotle. In the world of Aristotle, there are only single and specifically defined things with a given set of properties and assigned to one and only one category.

    Yes, now we have learned to speak not just "carry it, but “ carry firewood ” or “ carry stone ”. In their development, programming languages ​​focused on the fact that they learned to distinguish between objects ( firewood and stone ), but did not learn to distinguish actions on them. And in terms of the programming language, men.carry (firewood) and men.carry (stone) will be different language units, unless firewood and stone objects have a common ancestor! It’s just that the implementation of the “ what a person can wear ” interface by these objects will not help us out, because it will be two implementations, and, therefore, there will be two units of the source code.



    One of the main limitations of OOP is hidden here, which makes our programs more complicated than they could be, forcing us to use crutches in the form of design patterns to compensate for the congenital limp of OOP. When we try to determine whether a particular design of a software system suits us or not, we cannot consider this solution in isolation. We should consider it from the point of view of reasonable assumptions about how this design will be used as a consequence. If you translate this thesis into the language of “ firewood ” and “ stones ”, then it will sound something like this. Designing software objects “ firewood ” and “ stone", We must be aware of the Lord’s plans to improve the software system. Namely, we must assume that He will not limit himself to creating firewood and stones, but on the sixth day of the creation of the world he will create a person who will drag them.

    About inheritance

    Another limitation of OOP is that each object belongs to one and only one hierarchy (" is a") of classes, even with the possibility of multiple inheritance, has once and for all a given set of properties. For example, a red rose is a flower and a flower is a plant. This contradicts the reality in which objects can evolve, acquire new properties, and lose earlier For example, a rose can become a commodity, and then a gift. What class should be a gift-rose? A rose-product or a rose-flower? Another example. A person is born with a very limited set of properties: have age, weight, height, food, eat and spoil the diaper. Time goes by and it acquires new sets of properties: a school student, a buyer, a passenger, a soldier, a student, an employee, an entrepreneur, a spouse, a parent, etc. And maybe not. For example, not every person serves in the army, studies at a university, marries and becomes a father or entrepreneur. Or losing. For example, finished school, served in the army or divorced. Therefore, the same object must be able to belong to different classes and this set of classes must be dynamic, i.e. change during the evolution of the object and the software system itself. As a rule, restrictions are imposed on the set of classes to which the object belongs. For instance. To become a soldier, a person must be 18 years old. And if a person is a student, then in order to become a husband, it is necessary to pass a compromise. change during the evolution of the object and the software system itself. As a rule, restrictions are imposed on the set of classes to which the object belongs. For instance. To become a soldier, a person must be 18 years old. And if a person is a student, then in order to become a husband, it is necessary to pass a compromise. change during the evolution of the object and the software system itself. As a rule, restrictions are imposed on the set of classes to which the object belongs. For instance. To become a soldier, a person must be 18 years old. And if a person is a student, then in order to become a husband, it is necessary to pass a compromise.



    About posts

    Another OOP oddity: “Behavior is how the object acts and reacts; behavior is expressed in terms of the state of the object and the transmission of messages. " But wait, if I simulate a collision of two cars, which of them receives and transmits messages and which ones?



    About properties

    “The state of an object is characterized by a list (usually static) of all the properties of a given object and the current (usually dynamic) values ​​of each of these properties.” But does the property of the object belong to the object itself? I will say no. For example, we say this apple is green. But what does this really mean? This means that if we direct a source of light that is close in spectrum to sunlight, then this apple will absorb all wavelengths, except those that correspond to the green range, and an observer who is able to perceive the entire spectrum of sunlight will only see reflected green light. If the source or observer has a different range, for example, infrared, then the color of the apple will be black. Thus, a property is not an integral characteristic of an object, but it is a possible manifestation of an object in its interaction with other objects. For example, the property of an object “float on the surface” may manifest itself in interaction with water and may not appear in interaction with alcohol.



    About aggregation

    We say: a mop “consists of” (aggregates) brushes and sticks. But what does this mean? If we consider the mop as an object that can move in space, then aggregation does not appear in any way, we consider the mop as an atomic object and we are only interested in its total mass and size. But if we begin to load the mop and test it for strength, then aggregation will manifest itself as the interaction of its structural components with a brush and a stick and the test result will depend on whether this interaction occurs through driven nails or through grooves, spikes and glue. Therefore, aggregation is also the interaction of objects.



    About Association

    If we say that object (a) is the husband of object (b), then we declare that objects (a and b) are connected by association. How can this connection manifest itself? Firstly, this connection itself is the result of the interaction of three objects (a), (b) and object (c) (registry office, a registrar where this connection is born, and there, by the way, it may disappear). Secondly, it can manifest itself in the interactions of objects, for example, (a and b): joint spending of the family budget or the birth and upbringing of a common child. It makes no sense to ask a.isMarried (b), he can lie. But the function isMarried (a, b, c) is quite meaningful . Therefore, relationships, like properties, are possible interactions between objects.



    About identity

    “Identity is a property of an object that distinguishes it from all other objects.” What should really correspond to this statement? Let's say I repainted my car. For me, he certainly remained the same. But for the traffic police it will be a completely different object, which will receive a new state registration number. Another example. The wheels were removed from the car. Did the car stay the same? And if also the engine? And when will the car cease to be the same? Identity arises only when binding specific objects. Each mop will consist of a very specific brush and stick. Each husband will have a very specific wife, and each client will have his own copy of a bank account.



    So in our mental world there are no objects and their properties. But there are structures and their interactions. If we simulate traffic, then cars should be considered as elementary nodes of the structure, which, when interacting (overtaking, cutting, braking), consistently change their coordinates in the phase space (speed, position). On the other hand, cars cease to be elementary nodes of the structure, as soon as we begin to consider their interaction in a collision. We must move to a lower structural level. At this level, the elementary nodes should be: bumper, body, frame, engine and so on. components, as well as methods for their connection (bolts, welding, etc.). The very fact of allocating a structure node is an act of cognitive activity (Gestalt theory), which depends on the problem being solved.

    About the ontology of Ludwig Wittgenstein


    The world of Wittgenstein is not a world of things, like Aristotle's. If for Aristotle the essence of language is a noun, then according to Wittgenstein it is the essence of language is a sentence. Language, according to Wittgenstein, is not a set of names or properties, but consists of sentences in which the interactions of objects are expressed. In Wittgenstein's world, facts are primary - interactions between objects, and things are determined by the totality of their possible interactions. Such a view of the world corresponds very well to the modern theory of categories, in which morphisms determine the interactions of objects, and functors determine the evolution of a model in time.

    Unlike the static world of Aristotle, Wittgenstein’s world is dynamic. In the course of the evolution of the world, facts can be added and the idea of ​​things will change. Thanks to this interpretation of the world, a thing does not appear as something given, frozen, completely defined, but as some entity with fuzzy, variable boundaries. Software systems dynamically evolve like the Wittgenstein world. During the development of the software system, developers add new possible interactions to objects that expand the sets of their properties and relationships.



    Wittgenstein introduced the concept of “language game” - a single whole: the language and the actions with which it is intertwined. “How many offer types are there?” Say, statement, question, command? There are countless such types and the types of use of all that we call “signs”, “words”, “sentences” are infinitely diverse. And this plurality is not something stable, once and for all given ... ” Do we not play a similar language game when we describe a domain model using user stories?

    About Domain Specific Language (DSL)


    It seems to me that in the future, programming environments will be mostly similar to CAD systems with integrated DSL. Application systems should be created by specialists in the applied field, for example, an engineer will assemble a software model for studying the flight qualities of a new aircraft from a ready-made element base: the fuselage, wings, engines, connecting fixtures and models of their interaction with the incoming flow. Similarly, they will be assembled from ready-made components and business applications: accounting, logistics, warehouse, production, etc.

    Does this mean that for each subject area we must create our own unique DSL? Yes and no. Yes, in the sense that in almost all established areas of professional activity of people, for example, mathematics, medicine, biology, there is a specific language, so in each subject area we will have to create our own DSL to describe specific models for solving specific problems. No, because professional languages ​​are built on the basis of a single syntax of a natural language and there must be a universal syntax for describing mental models based on the general laws of human thinking.

    Attempts to create a universal DSL syntax have been made more than once. I will list only the most noticeable of them: one and two. I do not know examples of serious practical application of the proposed approaches. Maybe this is because they are trying to simulate the static world of Aristotle's objects in them? It is possible that the basis for the universal DSL syntax can be the dynamic world of Wittgenstein interactions and a categorical approach that reflects the fundamental features of our thinking.

    DSL like DNA should describe:

    1. scenarios for assembling a model from ready-made components;
    2. initialization of the initial state;
    3. laws of model evolution in time.




    The main building block of the language should be the interaction in which the properties of objects are manifested, their states change and new instances are born. Each object during evolution can be supplemented with a new set of potential interactions and this addition should not affect previously created code. The emergence of " man " in the world of " stones " and " firewood " with this approach will lead to the creation of a new interaction carry ( carrier, thing, space, gravitation ) ;. The carrier element must implement the interactions: take (carrier, thing) and move (carrier, thing, space) . And the thing element must implement the interaction:weight (thing, gravitation) and shape (thing, space) . In this case, our carry action model will turn out to be quite universal. The method will not change from the fact that a person implements take-up interaction with his hands, an animal with his teeth, and a crane with a special grip. Therefore, we can easily replenish our software system with any elements that implement the necessary interactions for carrier, thing and we do not need to change our universal function. What could it look like? Perhaps the future DSL will be similar to Mixin-technology or Anemic Domain Model (by the way, Martin Fowler called this model antipattern ), or to “ verbal programming»D. Knuth, where the narrative description of interactions will be interpreted in the form of algorithms and data structures.



    conclusions

    Programming is a new kind of human activity that is mistakenly classified as engineering.
    Engineering is an area where the laws of the natural sciences, mathematics, physics, chemistry are applied to design new products. Newton’s laws have not yet been discovered in software development, there are no Lagrange equations, or at least a compromise, which would help to design and prove the correct architecture of the new non-trivial software system.

    Programming is a humanitarian discipline and serious progress in its theoretical basis can be achieved only by using the achievements of the humanities: philosophy, psychology, linguistics, semiotics, etc. But for some reason, most programmers consider themselves engineers, not linguists. Perhaps after reading this publication, someone will begin to talk about alternative thinking.

    Also popular now: