Earlier quoted context omitted.
Any sort of thinking about what the code does or does not do is essentially proving theorems about it, is it not? It seems to me one does that all the time when debugging.
I don't think about coding that way. To me debugging is more like a Sherlock Holmes investigation rather than a formal theorem proving process. I guess we maybe work on different kinds of programs.
The simplest case is replacing an expression with its value, given an environment of lexical bindings that are apprent from the source program. Not much investigation necessary. That's FP.
For OO code, you just need to keep track of a lot more context: the state of the receiver of the currently executing method, its heirarchy of parent classes, the runtime class of each object because late binding is pervasive. Of course you can write code that doesn't use any OO features, but the languages clearly aren't designed for it. See: any number of "functional C++" articles.
And, of course, you can get the same kind of highly dynamic behavior in FP languages by explicitly using open recursion, higher-order state and hiding everything behind existentials. But very few codebases do that because the vast, vast majority of the time just one of these features is enough to solve a problem.