It has been a long-standing trend/belief/whatever that FP is just somehow better, it's kind of have been this belief that has endured for decades. Part of that belief is that exceptions are bad and option/result types are the way to go for proper error handling.
I don't think this is true at all, they are just different, with procedural programming being control-flow oriented and fp being dataflow oriented.
Monads are just dataflow oriented error handling, which is comes with its own set of tradeoffs and advantages, the key disadvantages being the necessity of an advanced type inference-system, to allow natural looking usage, and the function signatures having to support the notion that this function can indeed throw an error.
Implementation wise, the generated assembly is not more efficient, as the error passing plumbing needs to appear at every functions return site, even if no error happens.
I'm not saying Monads as error handling are an inherently bad concept, but neither are exceptions (as many usually suggest), and using both depend heavily on language support to make them ergonomic, which in the case of C# and monads, is missing.
On your definition of FP you're right. But pure functional programming has the following over regular imperative coding:
* Fewer bugs: Pure functions, which have no side effects and depend only on their input parameters, are easier to reason about and test, leading to fewer bugs in the code-base.
* Easier optimisation: Since pure functions do not have any side effects, they can be more easily optimised by the compiler or runtime system. This can lead to improved performance.
* Faster feature addition: The lack of side effects and mutable state in pure functional programming makes it easier to add new features without introducing unintended consequences. This can lead to faster development cycles.
* Improved code clarity: Pure functions are self-contained and independent, making the code more modular and easier to understand. This can improve code maintainability.
* Parallelisation: Pure functions can be easily parallelised, as they do not depend on shared mutable state, which can lead to improved scalability.
* Composition: This is the big one. Only pure functional programming has truly effective composition. Composition with impure components sums the impurities into a sea of undeclared complexity that is hard for the human brain to reason about. Whereas composing pure functions leads to new pure functions – it's pure all the way down, it's turtles all the way down. I find it so much easier to write code when I don't have to worry about what's going on inside every function I use.
That's obviously way beyond just having a declarative return type. And in languages like C# you have to be extremely self-disciplined to 'do the right thing'. But what I've found (after being a procedural dev for ~15 years, then a OO dev for ~15 years, and now an FP dev for about 12 years) is that pure functional programming is just easier on my brain. It makes sense in the way that a mathematical proof makes sense.
YMMV of course, but for me it was a revelation.