> if you can't run the program in your head, then you simply don't understand what's going on
Agreed, and sometimes it's surprisingly tricky to describe what's happening not in terms of the coding abstractions we all know and love, but just in plain English.
I remember I did a contract years ago for a PhD student which was basically doing some statistical analysis of a massive dataset. When I was doing progress reports she'd often drill down and ask, out of genuine curiosity (she was an academic, go figure :-) just how the computer was doing the things I was describing.
I couldn't use abstractions like 'well I just loop over this set and accumulate x and...' because that's gibberish to her - so I had to kind of break down what was actually going on in plain English (obviously with a degree of abstraction from the hardware etc). I did so very awkwardly because I was used to just 'thinking in code', but remember it was very helpful for me to be forced to do this because it really tested that I actually understood what my algorithms were doing.
But obviously there's a limit to the usefulness of this line of thinking. Abstractions are always present - ad adsurdium, we'd never talk about electrons flying around etc. It ceases (except in extremely rare exceptions) to be useful to describe what is actually happening in more detail than 'this black box does X, and I use it with another black box that does Y to achieve Z' right about the level where you're writing 'real' applications with frameworks and whatnot.