Most of Wolfram's discussion of "bugs" is not about the following situation:

You want a program that does X. So you think about what a program that does X should look like, and write a program that does what you think should produce result X, but maybe you made some mistakes.

but about the following, to my mind completely different, situation:

You want a program that does X. So you write a bunch of random short programs and after a while you find one that looks on small examples as if it's doing X. You use that one, but maybe actually it doesn't always work.

The key difference here is that in the first case you try to make there not be bugs by understanding what the program is doing and in the second you try to make there not be bugs by looking at the program's output.

(Perhaps some super-extreme practitioners of test-driven development might argue for something like the latter. Perhaps some AI-driven programming is uncomfortably close to it. But it's not, generally, how people have produced and debugged software.)

Wolfram kinda tries to justify this perspective by saying:

"Fundamentally the only way to make sure a program will always do what you want is to understand everything it can do. But there’s a kind of paradox implicit in that: if you can really understand everything your program can do that basically means the program is doing something computationally reducible, and you probably in the end didn’t actually need to run the program with all its steps to get the result you wanted."

but I think this is silly (and suspect it's the result of Wolfram trying to shoehorn his pet notion of "computational (ir)reducibility" into places where it brings no actual insight). It happens all the time that you write a program that (at least in principle) you understand completely, but that you don't know a much cheaper way to do it.

Computer scientists generally struggle with intensional contexts, ie., the sense in which sqrt(4) isnt (1 + 1); or the sense in which I believe(that sqrt(1101) ~10) but I dont believe(that 10^2 ~1101)

So they replace everything with extensional contexts, ie., in/out sets -- where things are replaceable by their values. And then use the machinery of very simple mathematics to analyse the situation.

In ML, consider comparing two classifiers extensionally, so that two classifiers "are the same" if they partition some input data exactly the same vs., declaring them different if they do so by means of some differing internal representation.

Since intensional contexts are the archetypal feature of mental representations, they're rarely analysed well by computer scientists.

I think its easy for us to think we can understand what a program is going to do when we're dealing with high level abstractions. I think if we really came to grips with everything the program is doing all the way down to the hardware level, we might have less confidence that we can predict what its going to do with 100% accuracy every time, even in the case of supposedly simple programs.