The growth stages of a programmer — FunFunFunction #6
Script of the video below:
Today, we are going to explore the growth stages of a programmer.
A couple of weeks ago I made a video that turned out to be one of the most controversial videos I’ve made so far. It was called straight-line code over functions, where I stressed that you should prefer simple, inline code over function extraction.
It got a lot of responses like this one, by mcostello:
Thanks for the rest of the videos but I have to respectfully disagree with this one. Testability, Composibility and Reusibility are completely lost when you don’t decompose into smaller units. I plead with you to take this video down before my co-workers see it and continue writing huge monolithic functions that do 50 different things.
mcostello, this is a fantastic comment. You are right that some people should not watch that video, because they will get the wrong idea, and it depends on where they are in their growth as a programmer, which is what we are going to explore today.
Blixt talks about three phases in the life of a developer.
1. The novice hacker
2. The philosophizing abstracter
3. The wise hacker
The novice hacker is like: ”This code sure is ugly and I don’t quite understand why it works, but here it is!”
This is when you’re starting out. You’re copy-pasting things from the internet, you don’t understand all of it, but it works, and you’re getting shit done.
As you get older as a programmer, you grow more and more into the role of the The philosophising abstracter.
The philosophising abstracter is like ”This code works for now, but if I move this part into a factory, and create an interface for these methods, it’ll also support all these future cases I can think of!”
As a professional programmer, most of your time is spent on understanding other peoples code. I’ve done this a lot. I’ve recently had the interesting experience of taking over code written by someone who isn’t a programmer by trade. I’ve never done that before. The person knows some programming, and has written a piece of software, but he’s doctor by trade, not a programmer. I expected his code to be incredibly messy and that I would have to spend a lot of time making sense of it. But in fact, it was actually the opposite. Understanding his codebase was much easier than most code bases I encounter at work.
His code *is* messy, there is duplication galore and spelling errors all over the place, but it doesn’t matter because the code is straight-forward. His code consistently takes the simplest possible path to solve a problem, and that makes it really easy to understand and read, even though it is the opposite of “elegant”.
In contrast, I’ve many times taken over code written by programmers that have a lot of knowledge about software design patterns and optimisation, and man have they used that. Their code does not have spelling errors. Their code has an abstract base class. You just need to implement this abstract base class, and pass it an object with any interface that inherits from a specific base interface, and everything will just work with logarithmic time complexity. IT IS MAGNIFICENT GAZE UPON MY CREATION
In a way, it’s all very impressively put together, but when it comes down it, that kind of code is really hard to understand. To figure out what the program does, you have have to move to this other file, and figure out what this concept does, and then remember that this other thing is being injected here. The programmer that wrote this thing did it with the best of intentions, trying to abstract away problems for you, but in doing so, they just made things harder for you.
And this brings us to Blixt’s third stage of programmer growth, “The Wise Hacker”, and the wise hacker is like “Move fast. Break things. Revise and fix. Get shit done.”
The wise hacker knows the same patterns and has the same optimisation skills as the philosophising abstracter — the difference is that the wise hacker knows that you should almost never use this knowledge. The key word here is almost. There *are* cases where you should optimise and generalise and modularise the hell out of a part of your code, and when that happens, the wise hacker knows how to do it and how to do it well. But the wise hacker only does it when absolutely necessary, because the wise hacker knows that generalization, modularization and optimization has costs. They are not universally good. They are not free. You need to get a lot of value out of them, or they will not be worth it. When you’re generalising, optimising, or modularising you are making a trade-off.
The wise hacker does generalise.
The wise hacker does optimise.
The wise hacker does modularise.
But the wise hacker only does that when it’s necessary. The wise hacker writes code that is stupid and simple and straight-forward as long as that is possible.
You have watched an episode of Funfunfunction, a weekly show where we try to become more confident and excited about programming by exploring old wisdom, wild ideas and having fun. Don’t miss out on the next episode — follow me on Twitter @mpjme.
Until next Monday, stay curious!