📜 ⬆️ ⬇️

OO VS FP

My translation , as well as the original report, caused mixed reactions in the comments. So I decided to translate Uncle Bob’s article response to the original material.
Many programmers in recent years have argued that OOP and OP are mutually exclusive. From the height of the ivory tower in the clouds, OP celestials sometimes glance down at the poor naive OOP programmers and condescend to haughty comments. Adherents of the PLO, in turn, look askance at the "functionaries", not understanding why they are scratching their left ear with their right heel.

These points of view ignore the very essence of OOP and OP paradigms. I'll put in my five kopecks.

OOP is not about the internal state


Objects (classes) are not data structures. Objects can use data structures, but their implementation details are hidden. That is why there are private members of classes. From the outside, only methods (functions) are available to you, therefore objects are about behavior, not state.
Using objects as data structures is a sign of poor design. Tools like Hibernate call themselves ORM. It is not correct. ORMs do not map relational data to objects. They map relational data to data structures. These structures are not objects. Objects group behavior, not data.
I think that here Uncle Bob scolds ORM for the fact that they often push him towards an anemic model rather than a rich one.
Functional programs, like object-oriented ones, are a composition of data conversion functions. In OOP, it is customary to combine data and behavior. So what? Is it really that important? Is there a huge difference between f(o), of() and (fo) ? What, all the difference in the syntax. So what are the real differences between OOP and FP? What is in the PLO, which is not in the OP and vice versa?

OP imposes discipline in assignment (immutability)


There is no assignment operator in “tru fp”. The term “variable” is not applicable to functional PLs at all, because once assigning a value to it, it cannot be changed.
Yes. Yes. OP apologists often point out that functions are first class objects. In Smalltalk, functions are also first-class objects. Smaltalk is an object-oriented, not a functional language.
')
The key difference is not in this, but in the absence of a convenient assignment operator. Does this mean that there is no changeable state at all? Not. In FP languages ​​there are all sorts of tricks to work with a changeable state. However, to do this, you will have to perform a certain ceremony. The change in state looks complicated, cumbersome, and foreign to AF. This is an exceptional measure, which is resorted to only rarely and reluctantly.

OOP imposes discipline on working with function pointers


OOP offers polymorphism as a substitute for function pointers. At a low level, polymorphism is implemented using pointers. Object-oriented languages ​​just do the work for you. And it's great, because working with function pointers directly (as in C) is inconvenient: the whole team needs to adhere to complex and inconvenient agreements and follow them in each case. Usually, this is simply not realistic.

In Java, all functions are virtual. This means that all functions in Java are not called directly, but using function pointers.

If you want to use polymorphism in C you will have to work with pointers manually and this is difficult. If you want polymorphism in Lisp: you have to pass functions as arguments yourself (by the way, this is called the pattern strategy). But in object-oriented languages, all this is out of the box: take it and use it.

Mutually exclusive?


Are these two disciplines mutually exclusive? Can the YaP impose discipline in assignment and when working with function pointers. Of course it can! These things are not related at all. These paradigms are not mutually exclusive. This means that you can write object-oriented functional programs.

It also means that the principles and patterns of OOP can also be used in functional programs if you accept the "function pointers" discipline. But why this “functionals”? What new advantages will it give them? And what can object-oriented programs get from immutability.

Benefits of polymorphism


Polymorphism has only one advantage, but it is significant. This is an inversion of the source code and runtime dependencies.

In most systems, when one function calls another, runtime dependencies and dependencies at the source code level are unidirectional. The calling module depends on the called module. But in the case of polymorphism, the calling module still depends on the called in runtime, but the source code of the called module does not depend on the source code of the called module. Instead, both modules depend on a polymorphic interface.

This inversion allows the called module to behave like a plugin. Indeed, plugins work this way. The plug-in architecture is extremely reliable, because stable and important business rules can be kept separate from changeable and less important rules.

Thus, for reliability, systems must apply polymorphism to create meaningful architectural boundaries.

Advantages of immutability


The advantages of immutable data are obvious - you will not face the problems of simultaneous updates if you never update anything.

Since most functional PLAs do not offer a convenient assignment operator, there are no significant changes in the internal state in such programs. Mutations are reserved for specific situations. Sections containing direct state changes can be separated from multi-threaded access.

Overall, functional programs are much safer in multi-threaded and multiprocessor environments.

Boring philosophizing


Of course, adherents of the PLO and OP will be against my reductionist analysis. They will insist that there are significant philosophical, philological, and mathematical reasons why their favorite style is better than another. My reaction is as follows: Pffff! Everyone thinks their approach is better. And everyone is wrong.

So what about principles and patterns?


What caused me such irritation? The first slides hint that all the principles and patterns we have developed over the decades of work are applicable only to the PLO. And in FP everything is solved simply by functions.

Wow, and after that you say something about reductionism? The idea is simple. The principles remain the same regardless of the programming style. The fact that you chose PL without a convenient assignment operator does not mean that you can ignore SRP or OCP, that these principles will somehow work automatically. If the “Strategy” pattern uses polymorphism, this does not mean that it cannot be used in functional PL (for example, Clojure).

Total, OOP works, if you know how to prepare it. Similarly for the OP. Functional object-oriented programs are generally excellent if you really understand what this means.

Source: https://habr.com/ru/post/338136/


All Articles