Waste, fast and slow

The problem isn’t the problem; coping is.

Virginia Satir

Throwing food in the trash feels wasteful. Sometimes I feel compelled to eat the food instead. Then I feel lethargic, I gain weight, and everything I do is slower.

Sometimes waste isn’t a problem. The world is not better for that food passing through my digestive system. Sometimes it’s preventing waste that hurts us.

Inefficient code uses compute and costs money. Even when the response time and throughput don’t impact the user, that’s still wasteful, right?

Waste that speeds you up

Say we optimize all our code. But then it’s harder to read and to change. We slow ourselves down with our fear of waste.

Duplicate code takes time to write and test. Maybe many teams use some handy functions for formatting strings and manipulating lists. It’s a waste to maintain this more than once!

Say we put that in a shared utility library. Now every change I make impacts a bunch of other teams, and every change they make surprises me. To save a bit of typing, we’ve taken on coupling and mushed up the code ownership. Everything we do is slower.

Waste that slows you down

On the other hand, duplicated business logic means every future change takes more work and coordination. That is some waste that will bite you.

In Office Space, there’s that one person who takes the requirements from one floor to another. His salary is a waste. Much worse: he wants to preserve his meager responsibilities, so he’ll prevent the people who use the software from talking to the developers. Everything is slower forever.

When you spot a distasteful waste, ask: does this waste speed me up, or does this waste slows me down forever?

I can be wasteful, and it’s okay sometimes. I’ll waste compute for faster and safer code changes. I’ll spend time on utility code to skip tripping up other teams.

Some waste is just waste. It is time spent once, or money spent ongoing, and that’s it. Some waste makes us more effective, saves us cognitive load of having to think about another thing. Some inefficiencies let us be more effective.

Other waste is sticky. It drags you into spending more time in the future. It pulls you into handoffs and queues and coupling.

Fight the sticky waste that spirals into more drag in the future. Let the other waste be. Throw the extra food in the trash; your future self will move lightly for it.

Other people’s messes

There’s a funny thing, that when I walk into the kitchen and there’s sunscreen on the counter that I left there before yesterday’s bike ride, there’s a plate that I put to soak on the counter and there’s a book about Klimt that I had hoped to read with my coffee, this is fine.

It doesn’t feel messy. I almost feel a comforting sense of continuity with my past self.

But when other people leave crab rangoons and cups and bowls and mail and washcloths lying around, ugh! mess!

It’s somehow different when I have the story behind it.

Code is like this too. If I remember writing it, then I know this nutty interface name was a placeholder. This ratty console.log helped me debug a tricky crash. I’m in the process of refactoring to use the new functions, but the old ones are still around some places.

When that’s anyone else’s code, it looks like trash.

This tells me: if the code is my own toy, and I’m likely to be back to it before I forget who I was when I wrote it, then all those intermediate states are fine. They might help me get back into this groove, even.

But if the code is shared, or if I won’t be back in it later this week, make small changes completely. One at a time, in series, so that each commit leaves the code clean. Put the sunscreen on and put it away. Wash the plate and put it in the dishwasher immediately. Take my coffee upstairs to drink with the book.

Sometimes I wish I lived alone, so I’d only have my own mess to deal with. I don’t want to code alone, though, except on toy projects. I do wish I lived with people who cleaned up after themselves. I resolve to make smaller messes in our shared code, one at a time.

For cleaner code, write ugly code

We want to write only clean code, right?

Wrong. I want to write eventually-clean code. It starts exploring a space, and then I refine it to be cleaner and more suited to purpose. Usually, that purpose becomes clearer through writing, reading, and using the code.

That process of refining or tidying up can feel tedious, compared to implementing more features. It can be tempting to leave off error handling. I have a strategy for that: meaningful ugliness.

When I’m prototyping, I make the code so ugly that it will be satisfying to clean up. No attempt at appearing clean. I put a bunch of casts, bad casing maybe, random names instead of plausible-but-inaccurate ones. No null-checking.

for (const gerald of allKindsOfStuff.fingerprints) {
    (gerald as any).displayName =
         allKindsOfStuff.feature.convertinate(gerald.name);            }

(exaggerated to show detail)

When cleaning, I often start by making the code uglier. To move from an OO style toward functional, start by replacing all global or class-level variables with parameters. Twelve parameters on a function?! That’s hideous! Yes. Yes. Let ogres look like ogres.

This lets me feel productive when I come back to the code and clean it up. Later, I know more about what this code is for, what might be null and what won’t, what dependencies I can eliminate and which are meaningful. This is a better time to clean.

Disguising rough code in socially-acceptable clothing prevents cleaning. Appearance-of-good is the enemy of better.

The next architecture book you must read

Today, another tweet about “how can I write the cleanest, best architected code?” gets piles of book references in response.

Yes, we want to be good at writing code. We want to write the best code. The best code for what? “Writing code” is an abstraction, like a transitive verb without an object. I can’t just “write code,” I must “write code to….”

The work is software development is not typing, it is making decisions. To make those decisions, we have to understand the details of code and technology, yes. We also have to understand the context and purpose, what we are writing the code to do.

My advice for “What should I read in order to write better code?” is usually, a book or magazine or internal memos about the business. Better is having conversations about the business with the experts inside your company, and to do that well, you need the vocabulary.

We need both the specific technical understanding and the business understanding. It’s so much easier to push for technical understanding. Because the business understanding is specific to each context. I can’t make a wide-audience tweet recommending a book, you have to find that closer-in.

Supplement Twitter with kitchen conversations or internal Slack channels that give you a broader perspective on the purpose of your work in the specific context you work in.

Zooming in and zooming out