Stop arguing about functional programming and OOP

    The post contains a certain amount of banter, the Ministry of Health convincingly asks an unprepared reader to refrain from reading.

    Articles on the topic “AF is better” or “OOP is better” resemble a debate about what’s best for lunch, a fork or a spoon. Traditionally, the junes started with a spoon, but someone very authoritative once told me that he only eats meat and uses a fork, so a new fashion has arisen - eat with a fork. They eat porridge and soups, and even manage to lap smoothies. The Internet is littered with articles, how good we are, that we learned to eat a smoothie with a fork and overcome all the rakes. This is both funny and sad, on the one hand, it gives a competitive advantage to experienced guys who show super results simply ignoring this hype, on the other hand, they have to retrain colleagues and employees, cleaning out the garbage caused by the wind from their heads. In this article I will try to tell my vision, which does not claim to be absolute truth, but works very well in practice

    As is customary in science, we begin with definitions. The classic definition of OOP involves following the principles of inheritance, encapsulation, and polymorphism. But if we do not have one of these components, will it be OOP? And if not, what will it be? While the boring part of the audience hovered over this impractical and giving nothing to us question, remember what happened before the PLO . And before him was procedural programming. And the main idea of ​​OOP at that time was in the connection of data and functions for their processing . The idea is simple, but quite revolutionary, it is difficult to imagine how much, but more on that later.

    Functional programming, in a free interpretation, considers the program as a mathematical formula. Formulas are well formalized and with the same input return the same output. The entire program consists of routines that follow the same principles. How does this differ from the same procedural programming? FP actively uses pure functions ; ideally, the entire program should be a pure function. Pure functions do not have side effects , they can be easily memoized, easily tested, etc. ... We can say that in pure functions the main idea and advantage of FP.

    And now two questions:
    - Can we use pure functions in OOP?
    - Can we bind functions to data in the FP?
    The answer to both of them is yes. Static class methods can be pure, even instance methods can be considered clean if they do not create side effects and we consider the properties of the class instance as parameters. The boundaries of classical definitions are inflated and some may disagree, but in practice it just works. And such methods are formalized and tested no worse than classic pure functions written according to all the canons. About binding methods to data is a little more complicated, the language and libraries used impose restrictions. Let's say in JavaScript this is done elementarily, not sure about Haskell and Erlang. Now the most interesting thing is what it gives, and why the OOP has already raised such a hype 20-30 years ago. If you write a small program - you can write as you want, except for your sense of beauty it does not affect anything. When you create a really big program, a problem of complexity arises. Not of computational complexity, we believe that here we are doing everything well, but of perceived complexity. Let's say you have 50,000 lines of code, and all of them are useful. How to organize them so as not to go crazy (or not to leave work at 11 nights)? We cannot reduce the number of operations, but we can reduce the number of connections between them (encapsulation helps us with this). We hide the complex implementation behind a simple interface and continue to work only with the interface. For example, the Internet is a terribly complicated thing, but most developers have enough knowledge of the HTTP protocol to do their job you have 50,000 lines of code, and all of them are useful. How to organize them so as not to go crazy (or not to leave work at 11 nights)? We cannot reduce the number of operations, but we can reduce the number of connections between them (encapsulation helps us with this). We hide the complex implementation behind a simple interface and continue to work only with the interface. For example, the Internet is a terribly complicated thing, but most developers have enough knowledge of the HTTP protocol to do their job you have 50,000 lines of code, and all of them are useful. How to organize them so as not to go crazy (or not to leave work at 11 nights)? We cannot reduce the number of operations, but we can reduce the number of connections between them (encapsulation helps us with this). We hide the complex implementation behind a simple interface and continue to work only with the interface. For example, the Internet is a terribly complicated thing, but most developers have enough knowledge of the HTTP protocol to do their joband leave the network, physical and other levels to system administrators . The weaker the connectivity of our modules, the less complexity at the stage of their integration with each other. The less one module knows about the other, the less connected they are. Binding methods to data inside the module helps us to get rid of this knowledge from the consumers of the module. This is the main pragmatic advantage of OOP. Above what? Above approach without data and method binding. FP, as we found out, does not say anything about this. You can pass classes as arguments to pure functions, or you can use pure functions as methods of a class, it does not contradict one another, but only supplements it.

    In practice, where mainly one approach works, and where is the other mainly? When i write backendon NodeJS, it itself somehow turns out in a functional paradigm. Why? Because the request to the server is by its nature a function, with a fixed input and output. The functional approach falls on server requests very naturally and the code is more compact and flexible. When I create a frontend for a browser, OOP usually works better , because in addition to input and output, we have a stream of user events, as well as program events, such as the beginning and end of animations, server requests, etc. ... The functional approach would work if you just needed to draw a static page without interactivity, when using the FP in the frontend, either interactive or development time suffers (according to our measurements, every 3 times). Why?

    Any programming paradigm is based on a certain reality model, and a model is always a simplification. In FP, the model imposes more restrictions on the world, so it is easier to formalize. For the same reason, when it becomes irrelevant to the conditions of the problem, it begins to require more crutches. For example, front-end FIs solved the problem of user input by creating an array of events (actions, redux hi). But this is an irrelevant abstraction, which, in addition to its performance impact, greatly increases development time. With this approach, you can create a todo list, but on really large projects you have to break bricks with your forehead, and then write victorious articles for the same unfortunate ones. For comparison, when we wrote the exchange terminal (on vanilla js, of course) with canvas,really great application ). If you program on the front end, you won’t even have such a thought, since you have already come to terms with immutability (by the way, this is a wonderful thing for working with multithreading, which does not happen in JS), so that every action goes through every reducer and other trash. On the other hand, in the backend it often turns out to do without classes at all, since there, just, you can avoid the cost of creating them, since the conditions of the tasks are very relevant to the FP model. But, for the most part, Java and PHP developers are in no hurry to study the FP, front-end vendors are in the forefront, who really need it the least. As an exercise for the mind - of course it’s interesting, only the programs are obtained g ... but, and someone else use them. Despite the fact that the frontend is a relatively young section of IT, and its unsolved tasks there for several generations. What, it would seem, is not an exercise for the mind?

    Also popular now: