My series about naming as a process is really about design. It focuses on design in legacy code. That has sparked people to ask about new code.
What about new code? Why not start with intent? I was taught to pseudocode or model, so that I could focus on the intent first. Then I don’t need all this after-the-fact concept discovery stuff.
- I always write new code with intent.
- I am never wrong about my intent.
- I’m never right either.
The problem is that I’m human and so is my thinking. Human thinking is fundamentally an associative memory game. We activate some set of memories and perceptions, and make new connections between them.
Our ability to think is limited by the size of our working memory. Which is tiny.
So I think of the best idea I can. I use my entire memory and Big Ol’ Brain to think about the problem and its solution. I write it down. I may use pseudocode or a model, but I find code-code to be the most expressive medium for expressing a program (if not, then the language needs a re-design).
The instant that idea is out of my mind it frees up all of my working memory. Now that full initial idea enters my perceptual sphere. It is fully present in my thought set, yet still leaves my working memory free.
In this instant I become a cyborg. Part of my memory is stored in my brain. Part is stored in my environment. Part of my thinking is happening outside my brain. I’m more thinking-capable (smarter) than I was before.
I fill the now-free human part of my brain. I activate new memories (other sections of the code, prior projects, other conversations with clients or other devs, etc). That invariably gives me a more refined idea.
Which I also want to write down, but now I’ve got a thought that depends on both things within myself and the existing code. It’s exactly the legacy coding situation.
Now I want to change the code to incorporate the new idea (write it down), yet still maintain all the original ideas that were in the first writing, even though those ideas are no longer in my head (because my head is full of the ideas necessary to maintain the new idea).
And so I refactor mechanically. IÂ change the code in a way that requires no thinking so I don’t have to dump memory (and my brilliant new insight) in order to make space. I change the code using techniques that are error-proof so I don’t lose any of the ideas that were present in the original writing.
If the first idea is incomplete, then pseudocode!
That used to be good advice. Pseudocode and modeling languages existed for a reason. They sacrificed precision in order to increase plasticity.
This was a perfect trade-off. The details were going to be wrong anyway. They let you put more of the idea into a single perceptual field. They gave you a bigger cyborg brain.
The spirit of the advice was simple:
- The medium for your initial thinking limits how well you can think.
- The most important trait for a medium is expressiveness.
- The second-most important trait is plasticity.
Modern expressive languages + the refactoring IDE changed everything.
Once I have zero-thought mechanical refactorings, changing code is actually easier than changing pseudocode or modelling languages. The code is more plastic than its abstraction!
Once my language has an extensible set of abstractions its expressiveness is unbounded. With a modern IDE I can even get dynamic views of the code (collapse method bodies, go to definition, go to callers, etc). This allows me to have both more detail and more conceptual information in my perceptual sphere at once.
And code remains the most authentic representation of code. It turns out a ton of insights come from those little details. They show the rough spots in the big ideas that cause us to re-think the big ideas. That’s why everyone changed their designs as soon as they translated them from models to code. precise implementation gives precise feedback.
So the spirit of the advice remains true. It’s just that the optimal medium used to be a model and now it is the code. Because our coding tools got better.
It’s legacy all the way down
New code is legacy code the instant your working memory is free of it and can have the next idea. As long as you are human (or a human cyborg).
I love that you mention that expressive language + refactoring IDE change everything.
Not knowing these is a bit like competing in height jump before Fosbury!
In my experience with C++ though, even doing the refactoring manually (applying recipes form Martin Fowler's Refactoring book) works well enough.
Thanks for this post