Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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!

share|improve this question
    
Answer here: ravimohan.blogspot.com/2007/04/… (note - you'll have to use the wayback machine for Jeffries' stuff, the original links are dead) –  Aaronaught Apr 29 '11 at 20:21
    
Are you really asking why thinking about what you are about to do is a good idea? –  JohnFx Apr 30 '11 at 16:32
    
No, I'm just saying, thinking it through in code is a better idea than thinking it through on paper. –  Tejaswi Yerukalapudi Apr 30 '11 at 20:05

11 Answers 11

up vote 3 down vote accepted

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.

share|improve this answer
    
Instead of opening a new answer, revise your old answer to be better. –  user1249 Apr 30 '11 at 8:43
    
Except that would mean totally changing it, which I think is not the intent. –  Rein Henrichs Apr 30 '11 at 8:46
1  
well, you changed your mind... so both answers are equally valid? –  user1249 Apr 30 '11 at 8:54
    
I think the other answer is valid. I just think this answer is more valid. I'm happy to merge them into the same answer. In general I worry about editing a post to totally change its meaning after it has gotten comments or upvotes, but in this case neither of those obtain. –  Rein Henrichs Apr 30 '11 at 16:17
1  
TDD : Test Driven Development. Whether I know how to do it properly or not is irrelvant to the question here. TDD is about validating the code you have writen against your design, not about designing it. –  DPD May 2 '11 at 4:15

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.
share|improve this answer
    
I feel once you have a system level design, say you're writing a function that interfaces with some API or implements some algorithm that's of a moderate difficulty, they can be thought through much easier by just writing code instead of, say, reading through the entire API documentation or writing pseudo code for the algo on paper? –  Tejaswi Yerukalapudi Apr 29 '11 at 19:14
2  
@tejaswi: It's easier in the cases that you're right :) However, when you just sit down and code, you're running with scissors in the dark. One of the things that seasoned engineers look for (especially in interviews) is that candidates do not just dive right into the code. You need to understand the problem in its entirety prior to solving it. –  Demian Brecht Apr 29 '11 at 19:23
3  
Exploratory coding can be a way to try to understand the problem. If you do that, use a language like Lisp or Python or Perl where you can write what you need without infrastructure, and throw it away when you understand the problem. Throwing it away is essential to making this work, so don't do so much work that you feel invested in it. –  David Thornley Apr 29 '11 at 19:52
1  
@David: Sure - using Python and the like for prototyping is tremendously useful. However, it's still easier to get a solid grasp on a problem in its entirety on paper than just sitting down and blindly hacking away at something. You will undoubtedly miss some technical issues in your paper design (which will be flushed out by the code prototype), but you'll still understand the big picture problem much better. –  Demian Brecht Apr 29 '11 at 19:56
2  
@Demian: I think this is probably one of those things that vary by individual and by problem. I've done both ways, and found both useful. –  David Thornley Apr 29 '11 at 20:11

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.

share|improve this answer
1  
Automating a broken process is like giving a child a chainsaw. –  JeffO Apr 29 '11 at 21:14
    
@Jeff: too true –  IAbstract Apr 29 '11 at 21:47

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) ?

share|improve this answer
    
I actually feel a bit differently about it. If the problem is trivial, then I should be able to know how I am going to approach it before I start to code. If the problem is difficult I might need to write some cheap tests of my ideas to make sure they make sense. Of course I would do some thinking before writing those tests, but there's nothing like running code to prove your ideas. –  T Duncan Smith Apr 29 '11 at 20:26
    
I was influenced a lot by Code Complete 2 and the pseudocode programming method, where you basically: decide the algorithm, write it in pseudo-code commented and then incrementally substitute pseudocode with real code. But in order to argue in favour of my opinion lets think a bit in lines of code. Would you follow the same approach if you had to handle a problem which would roughly translate to 10K LOC? 100K? Time constraints? A complex data structure (b-tree). Do you know the CLRS book? Why does it also have diagrams? It has to do though with each person's brain and how it comprehends. –  dimitris mistriotis Apr 29 '11 at 20:45

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.

share|improve this answer

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.

share|improve this answer

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.

share|improve this answer
1  
For a lot of folks, code is the easiest and most precise way to express the solution; in other words, the second "problem" is no problem at all. No one ever suggests that before solving a math problem, we should try to write the solution "in words". –  kevin cline Apr 30 '11 at 0:35
1  
@Kevin: expressing problems isn't the issue, expressing solutions is :) I'm not saying you plan out every line of code or class, but you need to know - or have a fair idea - where your going to end up as you start writing. The biggest waste I've seen junior - mid level developers make, is starting to codeca solution to a problem and they're unaware they don't know the solution. They get confused and bogged down in implementation details, they - wrongly - equate this with solving the first problem –  Binary Worrier Apr 30 '11 at 18:02
    
Some do, but not EVERYONE gets bogged down in implementation details. With modern languages, there is very little difference between design and high-level coding. –  kevin cline May 10 '11 at 22:39

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.

share|improve this answer

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.

share|improve this answer
    
No, that is definitely not what it boils down to. That's called "waterfall" development and it's a failed strategy. –  Rein Henrichs Apr 29 '11 at 19:03
    
other companies do iterative waterfalls where each iteration takes 6 weeks. My team does agile development. We still have release planning stage where we lay down stories (i.e. requirements) and before each story we still have a design phase where we review which components have to change and how that affects the rest of the product. And yes, we do this EVERY TIME before anyone writes code. Simple stories have design phases that last 15 minutes. I'm working on new server and we had "research spikes" which were all consumed by design and defining the foundation –  DXM Apr 29 '11 at 19:07
    
@Rein - DXM's suggestions are often required in many cases. I have personally seen it work. –  Ramhound Apr 29 '11 at 19:17
    
Perhaps. In any event, describing a full iteration lifecycle is not really an answer to the question. –  Rein Henrichs Apr 29 '11 at 19:19
3  
@Rein - I don't care for flinging around methodology names like waterfall, agile, xp... it doesn't matter. Our job as developers is to come up with solutions. A project, big or small, where you put any thought into a design, will be more readable, reliable and extensible. And regardless of methodology, if you don't take the time to identify real-world problem you are solving, then there's a good chance you are wasting your time on all that good design you are doing. –  DXM Apr 29 '11 at 19:29

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.

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.