While I agree with this in general, I find that to reall fully understand a problem, I need to attempt to code, or at least formulate, a solution to it.
a) because when I break down a problem into its code-able component parts, I learn a lot about it
b) because in the process of then actually implementing these parts I often discover edge cases or undefined cases (especially in naturally grown business-logic)
c) because what the problem actually IS, is often not that clear at the start of the problem. Yes, in an ideal world, changing requirements would wait until the next version, however, sadly that's not what happens in the wild.