Expectations: What it's like to write code
Writing code is a creative act. It requires focus and concentration. It requires a lot of thinking and deliberation. Thinking about what types of structures to use where, how to design a function or what should happen first. There is a lot to think about and there's usually multiple ways to attack the same problem. Just like painting a picture or writing an essay, it's a creative act that requires lots of thinking and the ability to make changes.
This will sound a bit whacky at first, but bear with me: writing code is not like flipping a burger. Flipping a burger is predictable and mechanical. Place it down on the hot grill, wait a minute or two, flip it and wait another minute. Take it off and it's done. It's easy to do this over and over and even predict how long it'll take to cook 20 burgers.
While some things are routine and predictable such as declaring a variable, writing code not something that is easy to predict. It takes time, design and careful thinking. It takes saying no to some things and yes to others. Good code is focused, bad code is flexible.
Future coding is a lot like playing the roulette. If you can guess where the requirements of tomorrow will land today, you’ve just scored the ultimate programmer’s prize: looking like a wizard. You saw the future and you were right! High five, brain! -DHH
After consulting for many years and writing code for many more, an obvious observation can be made: flexibility in code means future complexity. You see, if you keep building things to accommodate various edge cases or small use cases, then you'll continue building complexity. Once someone used that use case/feature you'll say to your self, "see, told you so." You accommodated another use case of your code. This is one of the worst things that can happen to a codebase. Building flexibility can become addictive (mostly to managers and salespeople) to the point where the code is so complex that it's faster to just start over building only what truly matters. Saying yes to everything builds complexity.
People think focus means saying yes to the thing you've got to focus on. But that's not what it means at all. It means saying no to the hundred other good ideas that there are. You have to pick carefully. I'm actually as proud of the things we haven't done as the things I have done. Innovation is saying no to 1,000 things. - Steve Jobs
Adding features can make things ugly and complex. It makes it hard to continue working on. Take a look at the modern laptops, especially Apple's. Most would say that they are functional and beautiful and they aren't full of features from the past 10 years. They don't have CD drives and they don't have floppy drives. Most of them lack phone jacks and removable batteries. Removing features is incredibly important. It allows them to make the computer smaller, thinner, lighter and more efficient. It allows for moving forward without being held back by bulky and slow cd drives. It reduces complexity because you no longer have to figure out how to fit a CD drive into every machine, and it costs less, too.
A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system. – John Gall[1]
You could look at just about any industry this way. Building the future is about streamlining and saying no. It's important to "pay down your technical debt"[2] every once in a while to remain streamlined.
When it comes time to pay down your technical debt, don't be afraid to break stuff. It's liberating, even energizing to tear down code in order to build it up stronger and better than it was before. Be brave, and realize that paying your technical debt every so often is a normal, necessary part of the software development cycle to avert massive interest payments later. - Jeff Atwood [2:1]
When you first start writing code, say a new project, you'll notice the relevant speed at which things are completed. As the project grows and you've written more code, you usually notice productivity start to slow down a bit. You'll start maintaining old features. It's important to look back on what you've done before moving forward to cut out things that no longer make sense; that no longer focus on the vision of the project. Deleting things is ok, and usually makes things much better.
A big aspect of writing code is understanding when something will be completed in the future. If I could have one super power, predicting the future would be it.
It's incredibly difficult to accurately predict when something will be done. The weatherman is never 100% accurate about the weather and neither is NASA about space and that's what they do best.
I have no idea when this article will be done, and I'm sure I'll change it a few times after publishing it. I can draw from past experiences that it typically takes me a few hours to write a post, so maybe this one will take a few hours. Writing code is very similar because it is a non mechanical creative act. I'm not a burger flipper, I'm the chef.
The more experience you have doing something over and over, the better you can come predicting how long it will take to do it again. Every time you change it, predictability goes out the window. The general rule of thumb for developers is think about how long it'll take you, then double or triple it especially when accounting for the unknown–it always takes longer than you think.
Imaginary work is always easier to do than real work. It is much more attractive (being more quickly done) and once you see the imaginary work, it can be very difficult to identify the real work it masks.[3]
Getting an estimation right is incredibly difficult and humans aren't the best at it. Think about it. How many miles away are we from the sun?[4]
If you haven't developed a project before where you are the developer, it's really hard to understand how much creative work goes into writing code. Flexibility can lead to complexity and a lot of confusion. It's best to revisit code every few months before adding new features to see how it affects everything. Flexibility exponentially grows complexity as the codebase gets bigger; even more so if backwards compatibility is required. Saying yes to saying no is one of the best ways to stay focused and build something great. It's ok if not everyone uses it. Not everyone uses an iPhone or an Android phone. Saying no is not a limiter of success.
If writing code to create something great was easy, people would have no trouble building the next billion dollar idea. Hindsight is 20/20. "Wow, why didn't I have that idea?" It's easy to get distracted looking back on things, but it's very difficult to look into the future. Your code will change dozens of hundreds of times before you hit the nail on the head.
Cover image from Fabio Pinheiro (Creative Commons attribution license)
http://blog.codinghorror.com/paying-down-your-technical-debt/ ↩︎ ↩︎
92,955,807 miles ↩︎