FP isn't well defined so these sorts of debates sometimes turn into a no true scotsman fallacy. For example laziness is pretty much agreed now to be a bad idea even though it's at the core of Haskell, the flagbearer for FP languages.

There are some other more subtle issues.

This article goes in depth into some less well known ones related to data structure efficiency.

https://jaxenter.com/disadvantages-of-purely-functional-prog...

The insistence on immutability comes from FP being closer to mathematics. But, computers aren't actually abstract equation solving machines. They are machines that spend much of their time copying data between mutable storage cells of various kinds. So, a lot of very important and common algorithms require mutability and don't have natural, efficient immutable equivalents. But FP requires you to be immutable, so, you can end up paying a heavy efficiency tax. Not many pure FP game engines out there!

Even when there are problems that are theoretically pure functions, like a compiler, real world compilers like LLVM or Graal are not functional, because you give up too much performance by doing that. Functional problems still benefit from not gratuitously copying data all over the place, mutating graphs in place, etc. Cache locality is too powerful an optimisation to give up.

OOP is fundamentally a paradigm about modelling a mutable world. It turns out that most software isn't implementing a pure function but rather a reduced model of reality, so, that makes it highly appropriate. Almost any database for example is a mutable model of reality (even if a fictional one like in a game). OOP languages have weak mutability controls, but fundamentally, a mutable variable is more "powerful" in some sense than an immutable one.

FP languages are often rather poor on things that OOP emphasises heavily, like encapsulation. FP gives you data structures and functions. Namespaces, usually. Beyond that it gets ropey. The core insight of OOP is that you often want to bind code to data very strongly, because that lets you really control the scope of functions much more easily. This in turn makes it easier to scale up teams, as people can more easily own their little corner of the world. OOP languages like Java have a lot of visibility control features, and are still getting more even in recent years.

Inheritance (subtyping) gets shit on a lot these days by the kids, but it's a very natural paradigm to model certain kinds of problems, for example it makes a lot of sense for GUI toolkits. Game engines also get a lot of good mileage out of it. Pure composition using layers is less effective, partly because it translates to worse machine code. Virtual method dispatch is highly optimised and thus a relatively efficient way to share and customise code. Interface dispatch is less efficient and proxying calls to composed inner objects, even less so again.

FP languages often end up trying to bolt on features to the functional paradigm that are natural fits in imperative OOP-oriented languages. For example, FP languages handle errors with a Maybe type and monads. OOP languages can do this too, but they can also do exceptions which are often a more natural way to handle errors, with various benefits. Strictly this is an imperative vs FP thing not an OOP vs FP thing.

There are some other issues that are less fundamental. FP languages are part of a family tree, and for whatever reason that family tree loves obscure syntax with lots of operator overloading. There are many OOP languages that are designed by industrial designers for usability in large teams, so they restrict how much of a mess you can make. FP languages are generally research languages that have little usage in industry, so FP code can often end up being very hard to read with a lot of bizarre custom operators. You could make a clear, easy to read and abuse-resistant FP language but nobody does.