When is better using functional programming, and when – OOP

SHARE

Many of us have heard about functional programming and may have wondered: “Why using it when there is OOP?”. We asked the experts when to use a particular paradigm.

Lead iOS-developer

OOP vs. FP is an eternal dilemma. It seems to me that the greatest efficiency in development can be achieved only if you mix approaches. It’s definitely not worth writing a project only in FP, because this approach greatly limits development: you need to constantly work out the behavior of state.

I would recommend that novice developers look at separate, specific cases. For example, a good case for FP is when the project has some kind of data sorting. Conventionally, there is a dataset where you need to filter data by last name, and then also by first name. Functional programming allows you to do it beautifully and smartly.

It is always worth thinking about the logic of the project. If there is a lot of dynamics in the application, then the REST API architecture from functional programming will work great. The same thing works vice versa – if you have a regular service application where JSON is displayed to the user, then there is not much point in using FP.

Frontend-developer

I believe that every developer should have an understanding of both OOP and FP; know the strengths and weaknesses of each approach and, based on this, determine what is best using to solve a specific business problem.

The OOP approach involves writing base classes and extending existing ones by adding methods to them. The data is stored in an instance of the class along with the methods that operate on it.

Functions in OOP depend on external data (for example, contain references to global variables within themselves) or communicate with the outside world (input-output).

Unlike OOP, functional programming is characterized by a loose connection between a function and the data it operates on. This avoids side effects when executing functions, such as reading and changing global variables, I/O operations, and so on. Deterministic FP functions return the same result for the same arguments.

But these approaches are not mutually exclusive. There is no need to choose only one paradigm and follow it to the end. You can pass classes to pure (i.e., not related to external data) functions, or you can use pure functions as class methods – one does not contradict the other, but only complements. If you are writing a simple and small program, following one or another paradigm is purely your personal opinion and vision of beauty. However, if you are writing a large service with diverse tasks, at some point you will face the need for refactoring, since one approach will not be enough to effectively solve all these tasks.

I’ll give you an example. If you’re writing in Node.js, it’s easier to use FP at first glance. The fact is that the request to the server itself is a function with a certain input and output (request, response). And the work with the request is done using a chain of functions (middleware), and the result (response) will always be the same if the same values ​​are passed as arguments. The functional approach looks natural here. On the other hand, if a Node.js service involves working with a database, it is more convenient to use an OOP approach to describe models and work with them. An example is the popular sequelize library.

In the great spaces of the frontend, frameworks are especially popular, and each of them uses one or another paradigm, but to fully work with them, you need knowledge of both OOP and FP. Take Angular as an example: this framework is built on services which in turn are classes containing data and methods for working with them. However, when working with the Redux library, which is usually paired with React, you directly encounter a functional approach since the main idea of ​​Redux is to use pure functions without side effects.

Senior Java Practice Software Engineer

“When to use functional programming, and when to use OOP?” – the question is quite difficult. If you look at the forums, it is clear that Holy War arises already at the stage of the very definition of functional programming.

If we proceed from the definition that functional style is when the result of code execution always depends only on the values ​​given to the input, then personally I try to apply this approach as often as possible.

This simplifies code readability and testing. However, FP is more characterized by the fact that the arguments of some functions are other, simpler functions, and this is the most difficult part where you can easily jump out for the complexity of O (n) calculations.

It is not very clear how to compare OOP and functional programming (FP). I believe that models can closely intersect, not excluding each other, and where which model to apply depends on the architecture of the program and the tasks facing each module of the program. For example, your code simulates the movement of a vehicle. It is necessary to calculate the coordinates of the vehicle every second, its speed, the distance traveled. In order to do this, it will be necessary to perform calculations based on previous calculations. If you apply functional programming, then it becomes necessary to store the results of calculations and submit them each time to the input of the model. This will create additional logical complexity, so it is better to combine OOP and FP in this problem. For each vehicle, an OOP-style object is created, and each object itself stores its previous calculations. All that remains for you to input is the acceleration, the direction of movement and the time during which they acted. Inside the vehicle object, you will have two dozen methods that calculate its new state. And here is the recommendation: strive to make most of them in the form of simple functions, and only in one or two calculations add the influence of its previous state or the set of functions used.

Now the threshold for entering the world of programming is very high, and it is unlikely that a programmer will be able to study one thing and be in demand.

Lead developer

Each tool is good for a specific set of tasks in a specific situation. Just as some can hammer screws, so fans of one or another paradigm, with any input data, can use what they are better at. However, experienced developers are still guided not by preference to any technology but by efficiency. There may also be restrictions set by the customer or the software environment. A number of factors and characteristics of the developed solution and its further support are important. Of course, the choice is more often based on one’s own experience, and at the very beginning of the development it is not always possible to guess the future design and all the nuances of using the software, so there is no universal solution.

Object Oriented Programming is the more “traditional” paradigm. With its help, an uncountable number of programs have been developed, including huge industrial systems in financial organizations, telecommunications in production, warehouses, and transport. Ignorance of the principles of OOP will actually block access to all these systems.

Here you need to understand that if you have been using OOP for ten years, then your consciousness adapts to this model, it is easier to design through objects and method calls, and not through data flows and data. One of the main disadvantages of OOP is the monstrous, confusing class system for a system that has been developed for decades by a large team. As a rule, some “core” classes end up at the “bottom” of the model, no one dares to touch them, even to the detriment of development speed and software stability. There are descendant classes, overridden methods and other garbage which eventually also becomes the “core of the system”.

As for functional programming, in some greatly simplified form, it is also used in OOP – at schools where the first programs are written with functions. You need to start learning programming languages ​​​​from it, and complete it with it. Further, depending on the needs of a particular project, one can deepen the knowledge of the paradigm that is more used. The FP paradigm affects both programming and software design. For highly loaded systems, the transition to processing data streams can be a lifesaver. To choose this paradigm in a “large” system, at least you need to have a lot of data and a lot of load (many calls, many users). On the one hand, it can distance the business model from implementation, on the other hand, it will allow timely response to requests from users and other external systems. For small programs, the choice of FP is possible, although it’s more a matter of taste. However, it can be difficult for a beginner to separate the business model into data and data flows and design it in a way so data is not stored in classes, and there is pure FP.

What should a beginner choose to study?

It won’t be possible to study everything at once, but to kickstart your career, in my opinion, it’s enough to know the principles of OOP and have at least a general idea of ​​functional, procedural languages: modern approaches use some older paradigms, in the new implementation they can be very effective. If you have a superficial knowledge of functional programming, this is generally wonderful. This means that the developer has a choice, fewer restrictions on the implementation of the plan.

All in all, which paradigm to choose?

The OOP approach involves writing base classes and extending existing ones by adding methods to them. The data is stored in an instance of the class along with the methods that operate on it. Functions in OOP depend on external data.

Functional programming is characterized by a loose connection between a function and the data it operates on. This avoids side effects when executing functions, such as reading and changing global variables, I/O operations, and so on.

However, these approaches are not mutually exclusive. You can pass classes into pure functions or use pure functions as class methods. Often a successful approach is precisely the mixing of paradigms, and not the use of just one.

When choosing a paradigm, you should look at the problem you are solving, and also take into account the possible development of the project, in order to be sure that the “correct” paradigm chosen today will not force you to rewrite the entire project in six months.

As for newbies, it’s definitely worth learning OOP as it’s a more “traditional” paradigm that’s used a lot. However, it is worth having at least a general idea of FP in order to have one more tool in your arsenal.