Throw away your first draft of your code
Monday, July 31, 2023
The next time you start on a major project, I want you to write code for a couple of days and then delete it all. Just throw it away.
And you should probably have some of your best engineers doing this throwaway work. It's going to save you time in the long run.
The usual approach
In software teams, a common approach to developing new features is something like this:
- The product manager collaborates with the engineering team to come up with a description for the next major feature. This probably will include acceptance criteria, and there will also be designs of varying fidelity.
- Then an engineer on the team takes point on the feature and decomposes it into smaller tasks which can be split out among the team. They take the high-level feature description and turn it into the complete list of all the things which need done to complete the feature.
- Some of these are open-ended if complexity is unknown or more investigation is needed, so they're timeboxed. The others are given some estimate (story points are popular).
- The issues are all assigned and loaded into the sprint.
- Then we go on our way and complete the feature and ship it on time!
Welllll we do all that, except we don't ship the feature on time. While working on this feature, we inevitably run into things we didn't anticipate. Maybe the data is messy in the database and we didn't realize that; now we need to add a data cleaning task. Maybe there was a portion of the UX that was more complex than we realized; that task takes longer than we expect. And maybe there was a portion of the technical design that was just suboptimal, and we had to redo it!
We can save a lot of this trouble and a lot of this work by making a quick and dirty first draft to throw away. What I'm talking about is prototyping.
When you develop a major new feature, product, anything, one of the defining characteristics is that you don't know what you're building. The only way you know what you're building is if you've built it before.
This leads to a problem: If you don't know what you're building, how do you know where the rough edges are? How do you know what the design demands, and what technical decisions to make?
Some of this you can glean from experience. I've been around enough blocks enough times to know that yes we do need to put in retry logic for requests. But there are usually some aspects that you just cannot predict, and some of these are unknown unknowns.
For the unknown unknowns, nothing beats exploring that territory first-hand. This is where the prototype comes in. When you develop a prototype, you get to actually go develop the feature a first time so that the real feature work is the second time, and you have more information. You know the database is a little messy, because you got in there and found out. You know that this section of the backend code is hard to extend, because you had to hack around it with a machete.
How does this work?
There's a mystique to prototyping, but the actual process of it is pretty approachable. For context, I'm talking about one approach to prototyping here; others could work as well.
The process for prototyping that I like to use at work is to take a rough, high-level description of the problem and give it to 1-2 highly skilled engineers to just implement. Give them a couple of days, and see where they get. (Yes, I like to be one of those engineers, but sometimes other people should get to have fun, too.)
Okay, that's a little bit "draw the owl"1, but it really does end up being pretty simple.
The directive for the engineers is not "make a complete feature" but "make something to demo if you can and figure out what's going to be hard." This is part of why I think prototyping work is often best completed with some of the more experienced engineers: They'll move fast, they'll learn a lot, and they have the context needed to know which parts to prototype the most for the investigation.
There are a couple of ways that this can be integrated into a team process:
- Organize hackdays! We do these at work, and they're a source of a lot of the ideas for and prototypes of major features that get into our product. When a feature comes out of one of these, it's already vetted and prototyped.
- Dedicate sprint time to a prototype. If you know a feature is coming down the road, you can get out ahead of it and give someone time to do a prototype before it makes it into a sprint. This is something we've done at work, too (I did a prototype like this recently, and we were able to save some time on a project).
So far what we've found is that features which have prototypes have much smoother development. Features which did not go through prototyping tend to hit more bumps. Some of these bumps might be due to the nature of the features (some are just not as amenable to prototyping), but prototyping could've helped with others. In that light, I've been pushing to get prototyping as part of our official process and the reception has been very positive.
Wait, do I really have to throw away the code?
Yes. All of it.
It's really tempting to hang onto the code after a prototype to speed up the feature development, but it won't do that. It'll just sabotage the prototyping. Keeping the code, and knowing that you might, completely changes the psychology of the prototyping phase for the worse.
If you know that you're possibly keeping the code, you do things in a "proper" way, which means moving slower. Put in all the exception handlers, all the log statements. Structure the code nicely, refactor things while you're in there, modularize them properly. After all, it's going to be reused.
If you do all that, you end up covering less ground and learning a lot less in the prototyping phase.
The alternative is you do go fast and make a mess, and then you keep that code? If so then I don't want to work in that codebase, it's going to be a mess.
So for the sake of the overall timeline, keep things fast and efficient by keeping your promise and throwing away the first draft. It empowers you to move quickly and learn a lot with a prototype, and then make better decisions that save time and effort when developing the real feature.
This refers to the "how to draw an owl" meme.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts and support my work, subscribe to the newsletter. There is also an RSS feed.
Want to become a better programmer? Join the Recurse Center!