Over the last several years I have paired with people learning Functional Programming who have expressed an anti-OO bias. This usually comes in the form of statements like: “Oh, that’s too much like an Object.”

I think this comes from the notion that FP and OO are somehow mutually exclusive. Many folks seem to think that a program is functional to the extent that it is not object oriented. I presume this opinion comes as a natural consequence of learning something new.

When we take on a new technique, we often tend to eschew the old techniques we used before. This is natural because we believe the new technique to be “better” and therefore the old technique must be “worse”.

In this blog I will make the case that while OO and FP are orthogonal, they are not mutually exclusive. That a good functional program can (and should) be object oriented. And that a good object oriented program can (and should) be functional. But to accomplish this goal we are going to have to define our terms very carefully.

-- https://blog.cleancoder.com/uncle-bob/2018/04/13/FPvsOO.html

OO is not about state. Objects are not data structures. Objects may use data structures; but the manner in which those data structures are used or contained is hidden. This is why data fields are private. From the outside looking in you cannot see any state. All you can see are functions. Therefore Objects are about functions not about state.

-- https://blog.cleancoder.com/uncle-bob/2014/11/24/FPvsOO.html

The thing that truly differentiates OO programs from non-OO programs is polymorphism.

-- https://blog.cleancoder.com/uncle-bob/2018/04/13/FPvsOO.html

The reductive definition of OO (Object-Oriented Programming) is:

The technique of using dynamic polymorphism to call functions without the source code of the caller depending upon the source code of the callee.

-- https://blog.cleancoder.com/uncle-bob/2018/04/13/FPvsOO.html

The reductive definition of Functional Programming then is:

Referential Transparency – no reassignment of values.

-- https://blog.cleancoder.com/uncle-bob/2018/04/13/FPvsOO.html

Functional Programming (1957), Object-Oriented Programming (1966), and Structured Programming (1968).

Three paradigms. Three constraints. Structured Programming imposes discipline on direct transfer of control. Object Oriented Programming imposes discipline on indirect transfer of control. Functional programming imposes discipline upon assignment. Each of these paradigms took something away. None of them added any new capability. Each increased discipline and decreased capability.

-- https://blog.cleancoder.com/uncle-bob/2012/12/19/Three-Paradigms.html

A well-written program will have an interface that complies to the Open-Closed principle:

You should be able to extend the behavior of a system without having to modify that system.

(...)

And this ought to give you a hint about what a jar, dll, or gem really ought to be. They ought to be isolatable features!

-- https://blog.cleancoder.com/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html

Sometimes a task will not br solvable fully functionally , eg: https://stackoverflow.com/questions/71588557/how-to-split-a-list-into-two-based-on-a-value.

It seems the simplest and most efficient solution in this patricular case is to have some mutation on the way.

In such cases, the best we can do is to encapsulate the non-functional code. This means that inside one function there will be some mutations of local variables, but outside of that function (including its callers) we can assume no mutation ever takes place.

And thus we have achieved the functional ideal: restricting mutation and loops to a single location, which in this case is the decorator tco, without any (severe) overhead.

-- https://sagnibak.github.io/blog/python-is-haskell-tail-recursion/