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!

3
  • 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, 2011 at 20:21
  • Are you really asking why thinking about what you are about to do is a good idea?
    – JohnFx
    Apr 30, 2011 at 16:32
  • No, I'm just saying, thinking it through in code is a better idea than thinking it through on paper. Apr 30, 2011 at 20:05

11 Answers 11

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.

8
  • Instead of opening a new answer, revise your old answer to be better.
    – user1249
    Apr 30, 2011 at 8:43
  • Except that would mean totally changing it, which I think is not the intent. Apr 30, 2011 at 8:46
  • 1
    well, you changed your mind... so both answers are equally valid?
    – user1249
    Apr 30, 2011 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. Apr 30, 2011 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, 2011 at 4:15
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.
7
  • 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? Apr 29, 2011 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. Apr 29, 2011 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. Apr 29, 2011 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. Apr 29, 2011 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. Apr 29, 2011 at 20:11
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.

2
  • 1
    Automating a broken process is like giving a child a chainsaw.
    – JeffO
    Apr 29, 2011 at 21:14
  • @Jeff: too true
    – IAbstract
    Apr 29, 2011 at 21:47
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) ?

2
  • 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. Apr 29, 2011 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. Apr 29, 2011 at 20:45
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.

3
  • 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". Apr 30, 2011 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 Apr 30, 2011 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. May 10, 2011 at 22:39
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.

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.

10
  • No, that is definitely not what it boils down to. That's called "waterfall" development and it's a failed strategy. Apr 29, 2011 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, 2011 at 19:07
  • @Rein - DXM's suggestions are often required in many cases. I have personally seen it work.
    – Ramhound
    Apr 29, 2011 at 19:17
  • Perhaps. In any event, describing a full iteration lifecycle is not really an answer to the question. Apr 29, 2011 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, 2011 at 19:29
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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