56

I was thinking today about Paul Graham's book "Hackers and Painters." More specifically, these two paragraphs:

"I was taught in college that one ought to figure out a program completely on paper before even going near a computer. I found that I did not program this way. I found that I liked to program sitting in front of a computer, not a piece of paper. Worse still, instead of patiently writing out a complete program and assuring myself it was correct, I tended to just spew out code that was hopelessly broken, and gradually beat it into shape. Debugging was a kind of final pass where you caught typos and oversights... [It] seemed like programming consisted of debugging.

... As far as I can tell, the way they taught me to program in college was all wrong. You should figure out programs as you're writing them, just as writers and painters and architects do."

That's how it's taught in my college and I'm pretty sure most other colleges as well. You figure out what your program will do, and then you figure out how to do it, then you type and debug. Sometimes you make a basic version and add functionality, but the idea is that you think through and then type.

This sort of reminds of that chapter in Feynman's book called "He Solves Radios By Thinking!" where he paced around thinking of how the radio could be broken, and then fixes it. To me, that's what programming is about - thinking and then finding a solution.

Is this the prevalent approach to coding? If so, why don't more people just hack away and put a program together without having a preconceived idea of what it's going to look like?

What are the advantages and disadvantages of think & type vs. spew & beat?

BlackJack
  • 3,867
  • 5
  • 33
  • 52
  • 5
    Every time I start trying to write code on paper I stop and ask my self why i'm using a pen a paper to begin with. – The Muffin Man Aug 06 '11 at 08:56
  • 2
    Kind of like a [Bob Ross](http://www.youtube.com/watch?v=MghiBW3r65M) approach to programming... no mistakes, just happy accidents. – Rei Miyasaka Dec 26 '11 at 05:27
  • 2
    [What if I told you](http://www.quickmeme.com/meme/3vn3hc/) that you can both plan ahead (think & type) and figure out as you write the programs (spew & beat) at the same time? – Spoike Aug 30 '13 at 06:36
  • possible duplicate of [Over thinking development](http://programmers.stackexchange.com/questions/200545/over-thinking-development) and of [What to plan before starting development on a project?](http://programmers.stackexchange.com/questions/69215/what-to-plan-before-starting-development-on-a-project) See also: [Develop fast and buggy, then correct errors or be slow, careful for each line of code?](http://programmers.stackexchange.com/questions/99980/develop-fast-and-buggy-then-correct-errors-or-be-slow-careful-for-each-line-of) – gnat Aug 30 '13 at 12:48

15 Answers15

70

This is a perfect example of the excluded middle fallacy. Yes, writing out the whole program on paper before you touch the actual keyboard is a bad idea. But that doesn't make the opposite extreme--immediately jumping into the coding and starting to hack away--a good idea. In fact, it's even worse.

It's very important to understand what you're trying to write before you start writing it. When I've got a new feature to implement at work, I make sure I've got a spec that describes what needs done before I start. I look it over, and if there's something on there that doesn't make sense, I talk with the people who wrote the spec and work over the issue until we're in agreement. Sometimes I hadn't understood the requirements and they can set me straight; other times the PM folks didn't understand the technical details, and they end up modifying the spec.

Just about anyone who's done this can tell you from personal experience that it's a whole lot easier to fix problems in the spec than it is to find a problem in your code halfway through the implementation, rip it all out, and replace it with something else. So having a plan for what you write before you start writing the code is very, very important.

Mason Wheeler
  • 82,151
  • 24
  • 234
  • 309
  • 5
    But demoware is a better spec than a flat document of 25 pages. Product Managers tend to change their mind once they see how this thing looks. That is the whole idea behind agile/scrum. – Job Aug 02 '11 at 21:06
  • 5
    @Job: I think the biggest spec I've ever worked from was about 10 pages. If it gets much larger than that, you're not working on **one** new feature anymore. – Mason Wheeler Aug 03 '11 at 02:36
  • 1
    The process of understanding what to write, may require writing quite a bit of proof-of-concept code. –  Aug 05 '11 at 22:11
36

You think Michelangelo just climbed to the top of the Sistine Chapel and just started drawing? Test drawings were made. Approvals from the Pope were needed. There was scaffolding to be built. Templates made to guide the group of other artists. The restoration was even more complex.

If I want to build an application and I don't have to consider the design preferences in someone else's head, I can just start coding. If you go down the wrong path, just change your mind. I didn't want that feature anyway.

Let the painter or writer sit in a committee. "Oh, just go ahead and make the main character a female. If we change our mind later on , we'll let you know. And WTF, let's make it 20' long instead of 30. Can you add a Spanish Galleon with 50 unique rowers before the unveiling tomorrow?"

JeffO
  • 36,816
  • 2
  • 57
  • 124
  • 8
    and can you paint clothes on them all? – jk. Aug 02 '11 at 22:41
  • It depends on what you are painting... – Garrett Hall Jul 12 '12 at 21:15
  • 1
    Bad analogy. Painting a ceiling is physically difficult, mistakes are hard to correct. Coding is like drawing in pencil, or sculpting in clay. – kevin cline Aug 30 '13 at 07:00
  • 3
    @kevincline except that once your code is being *used*, that *clay* becomes *concrete*... – AakashM Aug 30 '13 at 08:02
  • @kevincline A lot of (most?) good artists and sculptors will still do exhaustive "prototype" sketches and planning before starting the finished piece, even for a pencil drawing or clay sculpture. – Evicatos Aug 30 '13 at 17:28
  • @Evicatos: true, but what would you suggest a programmer build prototypes with besides code? I disagree with the notion that coding is somehow more expensive than some other possibly productive activity. – kevin cline Sep 01 '13 at 07:39
  • @kevincline The main reason for doing a study before a sculpture or drawing is the same as for doing prototyping before you code: make sure you fully understand the problem(s) involved before you start to build. Although I agree that code is a good way to do this, it's unfortunately much too easy to take sloppily put together prototype code and just toss it into production. I've been guilty of this enough in the past that I now force myself to sit down with just a pen and paper and make sure I completely understand the problem in my head before I start coding. ymmv though. – Evicatos Sep 03 '13 at 16:58
22

I think it is all about forming a balance. It is impossible to think of everything before you type it all out, which is precisely why the Waterfall model is so broken. At the same time, if you do too little thinking, you can cause a big mess for yourself when you get past the first several iterations. After all, you cannot beat all code into shape, and it would be very unfortunate if you had overlooked a basic requirement early on that required a rewrite half way through the project.

A certain number of iterations are required in the development process, which is what Waterfall overlooks (it assumes 1 perfect iteration). Agile (or the broad group of "Agile-like" methodologies) sometimes overlook that each iteration does have a certain amount of overhead, and if not much is gained through each iteration, the number of total iterations will increase and that overhead will add up to a significant cost.

Morgan Herlocker
  • 12,722
  • 8
  • 47
  • 78
  • 14
    Fun Fact: The Waterfall model that a lot of people think of is actually a model of a broken development methodology, not one that was ever intended to be used or implemented. See Winston Royce's "Managing the Development of Large Software Systems". – Thomas Owens Aug 02 '11 at 16:56
  • 1
    http://www.cs.umd.edu/class/spring2003/cmsc838p/Process/waterfall.pdf That paper? – JuniorDeveloper1208 Aug 02 '11 at 19:38
  • 3
    @toleero Yes. Figure 2 shows the traditional view of the waterfall. The text right below that explains why it should never be used. – Thomas Owens Aug 02 '11 at 20:29
22

The premise of the analogy is wrong: many writers outline or at least think out what they are going to write before they start writing, and many painters and architects will do dozens of studies and sketches before they start on their actual "work".

Given that the analogy is wrong, the answer is yes--programmers should work like writers, painters and architects.

Matthew Flynn
  • 13,345
  • 2
  • 38
  • 57
  • 7
    Programmers do the same thing - before writing a complex program, most of us hack up little proof-of-concept thingies to see if that idea we had in mind could actually work. The difference with painters and writers is that the material we work with is infinitely moldable, and copying is free, so we can start with a bunch of sketches and gradually transform them into a masterpiece. – tdammers Aug 02 '11 at 20:04
  • 3
    If you read Paul Graham's entire essay, he does, in fact, advocate building programs by "sketching", akin to an artist, so you're actually in agreement with him. – mipadi Aug 02 '11 at 20:28
  • +1 this was the interpretation I had when I read the subject, and the conclusion I reached. – SingleNegationElimination Aug 04 '11 at 22:00
  • Famously, Kerouak's *On the Road* was NOT written with any planning. Jack sat and wrote and when he was done, he was done. And then Truman Capote said, "That's not writing. That's typing." – Dan Ray Aug 10 '11 at 21:01
  • 1
    Well, it kind of shows. _On the Road_ reads well the first time, when you're young and really want to be traipsing across the country with no responsibilities, but it doesn't hold up that well. Moreover, it's inconsistent--some beautiful prose, and some clunky stuff. Kerouac got away with it--most wouldn't. – Matthew Flynn Aug 11 '11 at 02:55
  • I listened to a writer speak about his 10 year process of writing the latest book (Actually wrote for 10 and not just take 9 off and write for 1.). He met with a small group of reviewers once a week to go over and over his writing. The research was even more daunting and this was fiction. – JeffO Aug 11 '11 at 12:39
9

I had a roomate in college who was a double art major, doing painting and web design. He and I compared notes a lot about our workflows. When he paints, he doesn't just figure out the painting as he paints it. There were several things he might do beforehand. For a collage type of painting he might draw a sketch. On a photorealistic painting he would sketch out the major shapes with pencil and then paint in the details. But if he knew exactly what he wanted beforehand, he didn't need these aids. He just painted.

I'm sure you see the similiarities. We use different methods to aid in finding a good solution to a problem. If we don't know a technology well, we hack a bit to figure out what the final solution will look like. Larger products often benefit from a big-picture design session, with the details being filled in later. And sometimes we know exactly what is required, so we just code it. Not because we're lazy, but because through experience and thought we don't need the extra tools.

Some advantages to designing up front:

  • You see the whole big picture.
  • You can iterate through several designs without commiting to any. If you have code written already you cannot shift directions on a large scale.

Advantages to jumping into code:

  • On a micro level you have the ability to try a lot of things quickly before settling on the One True Parser
  • It can help break a design block. If you can't decide on a particular object model, say, you can build up a bit of code and see how it fits.

The answer to this question is like the answer to many in programming: It Depends. It depends on the project - do you need a design audit trail, does the process help you and your fellow developers fully understand the decisions you need, do they actively help you or are they holding you back from Getting Stuff Done? Is it critical that the project be absolutely correct, or can some flaws be discovered and fixed later? What is your time frame like? What experience can you bring to the problem? And finally, do you understand fully what problem you have to solve?

What works for me currently is to do a big picture design up front on paper. This will describe the major parts of the application and how they will communicate. Usually I draw am object diagram and some flowcharts/psuedocode/real code for the trickier sections. Then I jump right in, one section at a time. If a flaw in the model is causing a problem, I can always hop back up to the design specs and revise them for that area. And changing a good upfront design usually doesn't mean that more than a little bit will have to change.

Michael K
  • 15,539
  • 9
  • 61
  • 93
8

I was taught to program the same way you construct a model railroad.

When building a model railroad, you lay one piece of track and put an engine on the track. If it moves, you lay the next piece of track, and see if the engine moves onto that track. You continue until you've completed the loop, and the engine has completed the loop as well.

The advantage of this method of building a model railroad is that if the engine stops moving, you're pretty sure which piece of track is the problem. The one you just laid.

Programming is similar. You need to do the analysis and design, but at some point, you have to start laying track. Your first iteration might be nothing but dummy modules. That's ok, as long as your project executes without abending.

You add one method at a time (ideally), or the minimum amount of methods to get something to execute. Each time, you see if the engine moves (the project executes without abending).

You might discover as you're laying track that you need an additional siding (some additional methods). That's ok, as long as you're not radically changing the design. If you are radically changing the design, then stop coding. Spend some time thinking about the design and make the design changes before resuming your coding.

When you've laid the last pieces of track (finished the last methods), your project should execute without abending. Because you've been testing all along. Just like model railroad builders.

Gilbert Le Blanc
  • 2,819
  • 19
  • 18
  • I feel compelled to point out that no model railroad I've seen has loops, (aside from the whole thing being one big loop, of course,) subroutines, or conditional branches. – Mason Wheeler Aug 02 '11 at 18:13
  • 2
    Well, a switch controlled by the operator could be called a branch... – sum1stolemyname Aug 03 '11 at 07:22
  • This is great advice for the *programming* phase of a project, essentially saying "test early, test often." But IMO it's bad advice for the whole project: Surely every model railroader *designs* their layout, estimates what space is available, how much track will be needed, where they should start work, etc. – Steven Aug 03 '11 at 14:03
  • 1
    @Steven: Yes, most model railroaders design their layout. They even lay the track pieces without connecting them to check their curve radius math. Just as a programmer needs to do (or receive) a proper analysis and design before laying track (coding). – Gilbert Le Blanc Aug 03 '11 at 14:07
  • Of course a railroad has loops. What do you call it when a commuter line goes back and forth for a certain number of runs each day? Daily, weekend, holiday schedules, are all subroutines. In Boston, there is a special line just for a Patriots game. Like code, the loops, subroutines and branches are apparent during execution. Model trains also model the functionality of an operating railroad as well how they look. – JeffO Aug 11 '11 at 12:46
  • @GilbertLeBlanc you should add a note about "most ... design their layout". Your answer does not mention anything about a selection process of _where_ the next piece of track should go. –  Dec 26 '11 at 10:15
  • Trains! [Trains!](http://members.fortunecity.com/templarser/subway.html) which can be Turing machines – sq33G Dec 26 '11 at 11:13
4

The ratio of thought to action depends on a number of variables, ranging from the complexity of the problem to the domain to the end goals. There's no single one-size-fits-all approach to figuring out how much thought and planning you need up front versus when you can just "hack away" at a program.

If you have a complex problem or are working on something that is life or mission critical, you need to spend time understanding it and thinking about solutions and trade-offs up-front. If you want to quickly learn a technology, library, or framework, perhaps jumping right in and making your mistakes in a throwaway prototype environment work best. Other options include evolutionary prototyping - enough thought and design to make sure you can evolve your work into a finished product, but not so much that you get constrained down a single road.

Thomas Owens
  • 79,623
  • 18
  • 192
  • 283
2

Why don't more people just hack away and put a program together without having a preconceived idea of what it's going to look like?

Many people do just that, throughout their careers. This site is full of their questions. The other affiliate sites are full of questions by other people trying to use the software they wrote.

The kind of people who just spew out code, as you put it, will often say something like "Code is its own documentation". Code is not documentation. Code is not a demonstration of your intent, it's some version of what you remember as the intent, plus a bunch of stuff you got interested in along the way, some of which turned out not to be useful but you didn't have time to remove. Oh, and that amazing idea you had after two nights of no sleep but much caffeine, which was going to revolutionise the whole project, only know you don't even know how it compiles, let alone what it was supposed to do - or precisely what effect it will have if you remove it.

Without some kind of design document, however minimal, how do your collaborators (or successors) tell which bits to extend and which to drop? That document doesn't have to be written at the beginning, but for a project of any size and worth it needs to happen at some point.

Spew-and-refactor works for solo projects, up to a point (and people who are good judges of where that point is are worth knowing). It's less practical for teams; how do people work efficiently in parallel without some minimal consensus about the spec? Agile methodology is largely an attempt to resolve that problem without killing people's native enthusiasm for coding.

itsbruce
  • 3,195
  • 17
  • 22
2

As @Thomas noted, there is no one-size-fits-all solution. In this era of abundant computing power and memory, most of the problems we are facing with aren't difficult, so almost any approach will do which yields some correct solution. However, there are still areas where you can fail miserably if you try to figure out a solution on the fly, by writing code right away.

For example, one app I worked on was analysing mobile networks. If you need to write code to analyze a network of a couple of thousand nodes over a dozen different network layers, which is supposed to run not on supercomputers but mere dual-core laptops, you would better find the best graph algorithms known by mankind before starting to write any code. The alternative could be to realize after half a year of eager development that your algorithm, although provides correct results for your test network of 10 nodes, is O(n4) thus terminates after two years on the user's laptop, when fed with the real-life network plan he is working on right now...

Péter Török
  • 46,427
  • 16
  • 160
  • 185
  • 1
    When writing my post, I was thinking more about things like aircraft, weapons systems, and pacemakers. All the unit testing, integration testing, and simulation in the world is meaningless if you aren't absolutely sure about everything, from the requirements through the testing. You need careful planning to make sure that everything's been accounted for. Turning one of these devices on, in a live setting, could have fatal consequences if anything goes wrong. – Thomas Owens Aug 02 '11 at 17:17
  • @Thomas, indeed, life-critical software is not an area to learn by trial and error :-) – Péter Török Aug 02 '11 at 19:53
1

Generally, programming is an exercise in abstraction. Therefore, any attempt to over actualize any particular solution will undoubtedly lead you to misjudge the scope of your effort.

You are just not that good at judging complexity. Trust me, you just aren't.

The best code starts with an outline of what you want to accomplish and iteratively grown in chunks. With the successive code building upon itself. In the planning stages of a project it's much more useful to sit down and list what your program is NOT going to do. That way at least you don't succumb to trying to boil the damn ocean.

http://en.wikipedia.org/wiki/On_Exactitude_in_Science

0

Well, who am I to dispute what pg says, but... I think the best approach probably varies by individual, and that - to the extent that there might be an objective truth to this point - the truth probably lies in the middle somewhere. At the very least, I think making a dichotomy between "no planning ahead at all" and "figure everything out in advance" is a false dichotomy. It's a continuum, in my experience.

I personally lean more towards the exploratory programming style, and the "figure it out as I go," but at the same time, two of my favorite programming tools are an artists sketchpad and a set of colored pencils. There's definitely a time and place to sit down and sketch out high level relationships and visualize things to help yourself understand how things will fit together. Well, there is for me.

Again, I think this depends a lot on the individual... and also on the problem domain and the inherent complexity of the program. That is, a simple command-line calculator program (think, "poor man's bc") would probably require less up-front planning than an ERP system for a 30,000 employee company.

mindcrime
  • 520
  • 4
  • 6
0

I think the workflow is very individual for each programmer. Use the method that works best for you.

Me, personally, usually start with a blank paper and a pencil (or a very large whiteboard if I have one). I'm first drawing class diagrams and relations. Then I refine it until I have a basic structure. I also make the state machines at this stage. At this point no code has been written or thought of, only classes and relations.

Now this is only a lose sketch and while I start to program my classes I will run into more design questions. I then go back to my whiteboard (or paper) and break down the new problems, sometimes meaning ripping up some of the original design.

This is also similar to how Agile design works (note SIMILAR to all of you that will complain about this). There is a whole science on how to track the project progress using this method, because the number of new tasks will accelerate in the beginning and should fade to the end of the project.

The idea is to iterate code and design. We used this process in my former company (with 130 developers) and it works great. We also used Doxygen to produce class and relation diagrams from code. This was a quick way to get a good overview of the actually coded design, to spot flaws and missing relations.

If this works for you or not, I can't tell. You have to try and see what works best for you.

Max Kielland
  • 151
  • 2
0

I'll chime in with my two cents as well.

Writing out a full program on paper before you start is a "CS 101" exercise that works for Hello World. But spewing out code without taking the time to think about what you want to achieve is a waste of time as well.

Between these two extremes, you have the full range o software methodologies, from hard Waterfall (expansive set of specifications, pretty much one output at the end) to agile ("light" specs with very fast turnaround between releases and constant "customer" dialogue).

In any case, you need to know what you are building before you can start, whatever the methodology. This will help frame the program's architecture. Waterfall will put an emphasis on having the whole system architectured before you start coding, so that you know what you will end up with. Agile will put an emphasis on "spec the minimum functionnality to be achieved for the next iteration", and will admonish you to be prepared to re-arcitecture constantly (by creating suitable test suites and the like so that you can actually carry out such work).

Note that NO methodology will tell you to just start coding without a thought, and indeed, you should have a pretty good idea of what you are trying to do (be it the whole thing with Waterfall, or a smaller area with Agile). You do improvise somewhat in "HOW" you do something, not in "WHAT" you are trying to do.

I can draw a parallel with what you learn when taking acting lessons. One big part is "improv". When starting an improvisation, you need to come in with as little set in stone as you can, and be prepared to abandon your idea if someone takes the scene in another direction. You need great listening skills, and need to accept the others' propositions. The main thing is to come on stage with a character a situation, maybe a feeling you want to convey, and potentially an ending towards which you want to take the scene. But the furthest away the idea is in the scene, the more likely it is that you will end up somewhere else. In the end, it's a very "Agile" way of thinking, which might be what you are struggling with here.

Now, if you are talking at the "let's write code" level (specs, stories or whatever are available), then it's up to you. Some people do write pseudocode, some write comments before the actual code (in a "fill in the blank fashion) and some start by writing tests (see Test Driven Development). In any case, the goal is to frame your idea so that you achieve what you set out to do in your particular method. At that level, most people do some thinking before they write the actual code. But going so far as to write down the code before hand on paper seems overkill to me...

0

Obligatory Hunter S. Thomson quote but it always works for me

If you have a clear idea of what you want to achieve, know how to structure your code and are a good coder then its often quicker just to write the code.

James Anderson
  • 18,049
  • 1
  • 42
  • 72
0

I know this has been answered, but I'm not convinced Graham meant to disregard any and all high level overviews or design up front. I think about the problem before hand, have specs, etc., but still completely understand what he's saying as I work the same way.

To me the "hacking away" comes in not what you're going to do, but how you're going to do it. In school I was taught pseudo-code, and designing the actual code up front. To me, that's silly. I'll take a high level overview, a compass, and hack away from there. I'm not going to try to think of all the code because I'm not a compiler or a computer and can't comprehend the consequences of all my code-on-paper up front. I'll hack out an inefficient or broken implementation of the specs or design and then "beat it into shape" from there.

Bob
  • 101
  • 2
  • 3
    Pseudo-code made sense when we wrote assembly language. Today there's no reason to write pseudo-code. You may as well write high-level code in the implementation language. You can stub-out the lower level classes and have a running program, then implement the lower level classes to get a working program. – kevin cline Aug 05 '11 at 19:11
  • I sometimes do something that's similar to using pseudo-code, in that I'll write the comments for a particular bit of code, before writing the code. That is, I'll do a rough sketch of the algorithm in comments, then maybe come back and add in stubbed out method calls, then go back and implement those methods, etc. I don't *always* do this, but in certain situations it feels very natural and helps manage the complexity. – mindcrime Aug 10 '11 at 20:53