This is not true in my personal experience.
As has been famously said (paraphrased): Functional programming makes tough problems easy and easy problems tough.
In other words the value of functional programming depends on your domain.
Even in Haskell, which tries to control side-effects more, it's not hard; it's just that it's stuck with an "IO" annotation. Any function that calls an IO function also becomes an IO function; it's infectious.
main :: IO ()
main = putStrLn "hello, world"One way of viewing Haskell is that you are lazily constructing the single composite "effect on the world" called main.
helloWorld :: IO ()
then is a value representing an effect, but it only actually happens when it becomes a part of main.Threads complicate this but don't completely destroy the model.
That needs a qualifier: it can make easy problems tough if you're not familiar with how to solve them in a functional context.
A big part of that is because smart people have already solved the tough problems and made them available as language features or libraries.
All problems are easy if you are familiar with how to solve them. Unfortunately it's part of the problem to find out how to solve them, and that can be unusually hard in case of functional programming. Like solving something with recursion instead of loops + states. There is a reason cookbooks use loops not recursion.
My favorite example of this is implementing quicksort. It's significantly easier in C than it is in Haskell.
Oh please, what's so hard about
qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
where
lesser = filter (< p) xs
greater = filter (>= p) xs
:)folks, take that with a big ol /s, you would never want to actually use that algorithm. But the real deal isn't all that awful: https://mmhaskell.com/blog/2019/5/13/quicksort-with-haskell
They are also a lot less productive. It depends entirely on what you are doing.
If you try and turn F# into Haskell at home you may run into that problem.
F# is functional first language so if an object oriented or procedural solution is the right call the options right there when you need it.
And because of mutual recursion, that means that tough is easy (and easy tough). In other words, if we call the class of tough problems T and easy problems NT, we have T==NT, given FP.