1

Why is writing code when you encounter a tricky problem considered "bad" programming practice? And why is thinking a problem completely through on paper or in your head before you write code "good" ? From what I've been working with, I'm able to see problems in multiple different ways or special cases I didn't think of at first by typing out code and debugging than solving the problem completely first ?

Also, I can't really find any appropriate hashtags for this. So any help is much appreciated!

11 Answers11

5

It is worthwhile to think out any problem while coding, no matter how trivial you perceive it to be.

Why? (in no order of importance)

  • Your implementation can affect any number of different areas, and you may adversely affect dependents with your changes.
  • You can throw away paper designs a lot faster than re-writing code
  • You can have someone else vet your ideas easier on paper than trying to have them look through code that they're not familiar with
  • Designing on paper forces you to think through the entire problem rather than just the small chunk you're current writing.
Demian Brecht
  • 17,585
4

After thinking about my previous answer, I realized that the best answer to the original question is to present a third option: write tests. Test Driven Development combines the best qualities of "just writing code" with the best qualities of "thinking the problem through in your head". You can think the problem through in your tests instead.

Rein Henrichs
  • 13,230
2

My motto:

If it doesn't work on paper, it's not going to work in the computer. That goes for business process too. If you automate a broken manual process, you end up with a broken computer process.

Christopher Mahan
  • 3,414
  • 21
  • 22
1

it depends on the problem size :-) Also there is an element of "commitment". It is difficult to throw away code we usually spend time writing and debugging, while we can throw away some "paper" more easily.

It the problem is trivial, then yes you should code "only", but if there is a big algorithm with external calls/systems etc? Think a payment system of a large company or a video game or a database. Would you start from void main(args) ?

1

It's not always a bad thing, IMHO. But the key is that when you start writing code in order to solve a problem you don't fully understand you should be doing it in order to understand the problem better, and because it is the fastest way for you to do it. You should be willing to throw the code away once it has served that purpose. Concomitantly you shouldn't put any more work into that code than is necessary to serve that purpose.

I'm a big believer in prototyping certain difficult problems. I actually spent about 6 months last year just prototyping various aspects of a problem I am working on. I also did a lot of pencil and paper work during that time. The reason was that the problem really was very difficult (for me at least,) and also very hard to precisely define. So we would develop an idea for an approach, and then code a bit to see if it worked out. In a lot of cases that revealed that our idea was flawed, so we would go back, think up another approach, and then code up the simplest test of it we could.

One big danger is that you will start coding before you understand a problem and get so attached to your sub-optimal code that it winds up in the finished product. Another is that you will spend way too much time "gold-plating" something that is never going to work.

One way we avoided this was implementing our prototypes using a higher-level (and ultimately too slow) language and a much lighter-weight platform than we were eventually targeting. We ignored a lot of the rules of good software engineering- our code was not meant to live much past the point where it had answered our questions satisfactorily so over-engineering it would have been a waste of time. We did the absolute minimum we had to to get the answers we needed. And we worked as much as we could out on paper or a whiteboard before starting a prototype.

I'm a big believer in thinking things through as far as you reasonably can in advance. But sometimes you need to code something up to make sure what you are thinking makes sense. When to think and when to code (well, hopefully you keep thiniing while you code ;) ) is a hard question, and like a lot of things in software development, a matter of judgment.

EDIT: The main thing I wanted to get across here is that I think it's important to know why you're coding. Some code is meant to wind up in production. Some code is meant to answer questions. Where you get into trouble is confusing the two.

1

Different problems require different approaches to solving them. For example...

When I go about solving problems with bad data or misunderstood data in a database I find it very helpful to create interactive views (constantly modifying filters) to narrow down the issue. When I think I have identified the issue or pattern I then beef up the view or create several views to validate my assumptions. Then I move on to thinking about how to fix the data.

When developing a process from scratch I like to use yellow stickies (turning them 90 degrees for decisions). This lets me move them around, insert inbetween, or rearrange them until the thought process and flow has been worked out and I feel comfortable about writing code.

There are other times where I need to create something that is similar but different to something I've already created. At this point I usually make a copy of the original code and start commenting out chunks and adding new chunks.

1

When you try to solve a problem while writing code, you're suddenly faced with solving two problems

  1. The problem you started with, and
  2. How to express the solution for 1) in code . . . and you don't have that solution yet.

Some folks (who tend to take the second approach) think that these are the same problem, but nope, it's two problems.

Solving 1) before you start 2) means you're not trying to solve two completely different problems, you are focusing on the most difficult problem and getting that out of the way first.

0

The former is commonly called "coding into submission", and it's "bad" when it causes you to create overly complex, poorly designed solutions that could have been simplified by some amount of thinking before doing. However, writing a prototype solution in code can be a useful aid to thought as long as you don't try to put the prototype code into production.

On the other hand, the latter (when taken to its logical extreme) can also be "bad". Too much time thinking means not enough time doing. Perfect is the enemy of good, and so on.

The best thing to do is the simplest thing that could possibly work. This means thinking just enough about the problem to come up with a reasonable solution (and no more) and then trying that solution out. Try to find a good balance between thinking and doing.

Rein Henrichs
  • 13,230
0

If you look at all approaches (some would call them "methodologies") to developing software, it always boils down to:

  1. Define requirements - what exactly are you trying to solve.
  2. Define functional specifications - if you have multiple modules, how are they going to interact with each other. What are inputs, what are outputs
  3. Define software design of each module
  4. Code

A mistake done early on, will always be the most difficult to fix after your code is written. If you have a coding error, usually you can fix it within few lines. If you have a design error, you'd typically need to go back, redefine your classes, move things around and come up with new interfaces. If you made a mistake in the requirements, your design may not even be solving the right problem.

This is why they say that instead of jumping into code as soon as you in front of a computer, take a step back and actually define what exactly you are doing and make determination at that point given the scope of the problem, how much requirements and design should you really do upfront. It may take more time in the beginning, but 9/10 times it saves a lot of time down the road. And even for simpler projects, I would recommend going through the motions of layout down design because it's always a good practice for the future when you start doing not-so-trivial work.

DXM
  • 20,022
0

I don't think it's always a clear good/bad issue, it depends a lot on the coder. I have no doubt that there are some people who are completely effective at seeing solutions to some problems clearly in their mind, and can starting to code solid first drafts without having to draw things out. For most people, myself included, problems past a certain degree of complexity do tend to lend themselves to some pencil and paper work.

That said, where you get into the "bad" practice is when someone who can't clearly visualize the solution to their problem starts throwing down code instead of doing the thinking and design work they need to do. Rein calls it "coding into submission" in his response, I personally call it "debugging things into existence". No matter what you call it, it tends to yield poor results with unhandled edge cases, more than the necessary amount of code and poor organization.

0

Sometimes it's better to grab a stool instead of a hammer. In code we don't think this applies because bad code doesn't do permanent damage - just undo it or restore the backup. The problem is when you leave the code you just banged away because it 'appears' to work. You can just keep nailing enough boards to patch a leaky roof only to find you've been diverting the water to your electrical panel.

The real problem is inexperienced programmers may not be aware of all the elements involved.

JeffO
  • 36,956