Programming Proverbs 1: Define the problem completely

This is the first of a series of posts based on the book Programming Proverbs by Henry Ledgard. The index for the series is an earlier post and discussion of the list as a whole is taking place in the comments there. Comments on this "proverb" are of course very welcome here.

For a lot of people "define the problem completely" seems pretty obvious as the only right way to do things. To others, especially lately, there seems to be an idea that one should throw something together based on partial understanding, take it to the end user to see where they are, and then go to the next step. This really seems like a waste of time to me. Oh to be sure there are often times when the end user doesn't know what they want when a project is started. Someone commented earlier that "Walking On Water and Writing a Software is easy, if the Water and Specifications are FROZEN." There is some truth to that.

Historically software developers have lived with the idea that the specification will change and things will be come if not clearer at least different. That often makes it difficult, if not impossible, to define the whole system before starting.

But actually all of that is both a digression and a missing of the point. While for some people this proverb means understanding the whole system that is often, some would say always, a problem. And I think looking at that large a picture misses the point. I think that at some point one has to reach a granularity for which this proverb makes complete sense. That granularity is when one reaches a point when the amount to be coded by one person is reached. Is that a method? A class? A module? A complete program or even a small system? At that point it is a mistake not to have the problem defined and understood completely. To do otherwise is to ensure that the code will break when it comes into contact with expectations of the user or of other code. Code that is checked in with other code and does not work as expected means that the problem was not defined completely enough and someone started coding too early. There is no excuse for that in my opinion.

This idea of defining the problem completely has interesting ramifications for the teaching/learning environment. When a teacher defines a project for an assignment or an exercise for a test they assign to students there is an obligation to spell out the requirements completely. If there is ambiguity it should be there on purpose and to allow some leeway in problem solving. Students have an obligation to read and understand the definition completely before beginning to write code. Alas they seldom do. They are a lot like some professionals I have worked with I am afraid.

What I used to say to students was "I am much too lazy to write a lot of extra words so if they are there you'd better read them all." Assumptions are risky business and no less so where graded work is involved. I encouraged questions and often I re-wrote project assignments to make sure I answered those questions in the future. This was valuable both to the student, who learned to ask questions, and for me as I learned to better specify what I wanted. We never stop learning.

What is the problem? What are your inputs? What are your outputs? What do you need to know and to do to get from the inputs to the outputs? Unless those things are defined it is much too early to write code.