Skip to content

02 · Working code is not the bar

When you finish this lesson you should be able to:

  • Tell tactical programming from strategic programming in your own work
  • Choose a small structural investment that is worth the minutes it costs
  • Say out loud when “good enough” is a real decision, not an excuse

A function that passes today’s tests is a low bar. The interesting question is: what will the next similar change cost?

Tactical programming hunts the shortest path to green. Duplicate a branch. Add a boolean. Special-case the caller you have in front of you. It feels fast. The bill arrives later as fan-out and surprise.

Strategic programming still ships. It spends a little extra time so the next person (often you, in twenty minutes) has a place to put the next rule. Not a platform. A seam.

How much to invest? Enough that the module’s interface still makes sense after two more asks, not enough that you invent a framework. If you cannot name the next likely ask, you do not have enough information to generalize—so don’t. If you can name it (“we will add another channel,” “we will add another experiment audience”), hide that variation now.

Startups and crunch weeks do not repeal this. They change the size of the bet. A 90-second rename and a 4-line helper can be strategic. A six-week abstraction layer during a one-hour coding session is not.

You are parsing a stream of events: signup_started, signup_completed, message_sent, message_failed. The prompt is “count completed signups per day.”

Tactical: one loop, a string compare, a hashmap, done. When the follow-up is “also count failed messages, ignore duplicates, timezone is UTC,” you grow a thicket of ifs.

Strategic enough for an hour: a named function applyEvent(state, event) and a named function isDuplicate(state, event). You still finish part 1. The follow-up has a place to live. You did not build an event-sourcing framework.

The tell: after the first green run, you spend two minutes asking “what is likely to change?” If the answer is “the set of event types” or “what counts as a duplicate,” those become names, not comments.

Blank file or paper. Talk out loud.

  1. Write a four-line plan for: “given a list of {userId, type, at} events, return the latest type per user.”
  2. Implement the smallest correct version with named functions, not a single anonymous blob.
  3. Name the next two asks you would expect (out of order events? missing at? two events in the same millisecond?).
  4. Say which of those you would handle now, and which you would flag as a risk and skip.

Stop at ten minutes. Working code that you can extend beats a clever one-liner.

  • A Philosophy of Software Design — Chapter 3, Working Code Isn’t Enough
  • The Pragmatic Programmer — Topic 5, Good-Enough Software