I can't answer this question. I'm definitely visual, but I'm intrigued at any alternatives anyone could try to explain.
I can't answer this question. I'm definitely visual, but I'm intrigued at any alternatives anyone could try to explain.
I rely more on feelings rather than visualizations. For example I don't usually visualize the hierarchy of a program. I feel my way around it. I'll use my editor/debugger/REPL to jump me from place to place to build up a non-visual structure of the program in my head.
If I need to communicate the hierarchy a block diagram, UML diagram, ASCII art, English prose may be drawn but that's not what's in my head at all when I'm working.
More importantly I'm often feeling for inconsistencies and patterns. Most importantly I'm feeling for elegance and simplicity. If one thing seems a little bit different than a couple of other things I'll make it be the same. If a number of things feel the same I will abstract out the commonality. Visualization does not help me do those things at all. I need to load the program into my mind and then I just start noticing/feeling the essence/problems/cleverness/joyfulness/messiness etc.
I think you're right that when it comes to learning something quickly or communicating something a visualization helps greatly.
More strangely (to most people with whom I have spoken), I often dream entirely without images--occasionally even as written prose.
Edit: Perhaps interestingly, this does not seem to harm my ability to do spatial inference, but I have essentially no long term image recall.
I usually think of my mental model of the code as being a map, yet it's not a visual, 2D map. It's more a collection of associations - I know that if I follow this function, it'll have this effect on the world, and this function is used from 4 other places, all of which need it to do this, etc. It doesn't really map well onto 2D visuals at all, because I suspect code has way more than two dimensions. But maybe like a massive graph lattice...
I use the same mental mechanism for getting around town, so it's definitely spatial, but not necessarily visual. I guess the best distinction I can draw is to compare looking at a map of a town, vs. actually living in the place. For example, I got lost today in a twisty residential cul-de-sac while hunting for an estate sale that never did materialize. But I knew I was in the corner between 101 and 85, and I knew I'd come from Middlefield, so in the course of driving around I managed to put together a mental map that got me out of there. (FWIW, I was here: http://maps.google.com/maps?f=q&source=s_q&hl=en&...).
I find that I can't stand visualizations of software - they always confuse me far more than just looking at the code does. I'm not sure why - maybe it's because it's a leaky abstraction, and there're always connections that are very necessary that aren't represented on the diagram.
But again the graph idea is a formalization. It's more fuzzy and messy in my head. The graph is not perfect and requires care and feeding to stay alive. And you don't actually see the whole thing at once. You can move around inside it but there is a focus. It's something your subconscious operates on as much as your conscious mind. And it's the subconscious that generates the intuitive flashes.
This is interesting because I am a "visual" developer and have never really used a gdb-style debugger at all in nearly 10 years of professional dev experience.
I prefer isolating problematic code programmatically and refactoring my mental picture of the architecture/data structures until I can mentally visualize what's going wrong in my math/logic. This has given me grief with hairy pointer code where running something like 'printf' actually changes stuff in memory that you're trying to look at, but I really just don't understand how anyone can use a debugger to step through things one line at a time when that's essentially what I'm doing in my head when I look at code.
Then again I've never worked on anything as complex as, say, an OS kernel, so what do I know.
Depending on what you mean by "isolating ... programatically" it might be very similar to how I sometimes use unit-tests in general or the REPL when programming in a high-level language such as Lisp or Python.
The unit-test/REPL lets you play with functions on an individual level. Checking inputs and outputs. Slowly synthesizing more complex arrangements which approach the problematic arrangement actually found in the real code.
All of this is about augmenting your intuitive understanding of the code with real solid empirical data about the behavior of the program. If you can't explain a given bug your intuitive understanding is somehow wrong or lacking and often you'll see surprising behavior when you actually instrument the program. Those surprises lead you to the solution.