https://www.quora.com/Why-is-functional-programming-suited-f...
Functional programming is also easier to mathematically verify than imperative:
https://semantic-domain.blogspot.com/2018/04/are-functional-...
While you might not do proof, languages and methods that are easier for proof are often easier for automated analyses that look for problems, too. There's tools out there that can check code for concurrency problems that are extremely hard to spot with just testing. They might be easier to build or get more results if the program was functional/stateful instead of heavily stateful.
https://github.com/project-everest/hacl-star
You can verify stupid designs or smart ones. You can do impractical verification or pragmatic approaches. Formal verification is a tool whose outcomes depend on who wields it. The only consistent drawbacks it has are requiring more expertise, the project takes longer, and the project has to be simplified in design/implementation. High-quality software in general (eg OpenBSD) often has same properties, though. Possibly intrinsic to achieving correctness rather than additional requirement of formal methods.
Of course, you can still deadlock yourself; and read-modify-write can still be done in a racy fashion. Emergent properties of a system are still hard to reason about, but individual processes should be easy to reason about.
Low-level code correctness is overrated. With some experience it's trivial to achieve even in a crappy language like Java. Nothing except horrible syntax stops you from writing "functional" code in Java (and even that became easier in Java 8). This is what I and all sensible engineers I know are doing. In my experience, this "weak" version of FP plus a few tests is enough to virtually eliminate low-level coding bugs.
You can still get some surprising behaviors from 3d-party libraries and stronger FP can help with that a bit, but it's nowhere near as drastic of an improvement as many people present.
There are two big classes of errors I do often see in real life.
1. Spec omissions aka systems Broken As Designed. Your system works the way you expect it to work, but produces results users did not anticipate.
2. Emergent problems. Like someone shutting down your service for a day, causing queue backup, causing a huge batch of data being sent to vendor when the service is back online, causing vendor to throttle you, causing all other jobs being delayed.
#1 seems to be mostly a matter of experience and knowing when to show people some diagrams. OOP and especially agent-oriented programming can actually help you when reasoning about #2.