Header photo by RhondaK Native Florida Folk Artist on Unsplash
I’m a full-stack developer, which means I’m a generalist. I believe that generalism in software development is a good thing. But many developers, engineering managers and even CTOs think that generalists are a risk and that what software teams really need are specialists.
Because apparently, generalists can’t be very good at what they do. After all, software systems are far too complex these days for any one person to ‘know’ their system inside-out. Right? And how could a generalist keep up the same pace as specialists when everything changes so fast? Surely they can’t hope to remain relevant? Surely a generalist can’t be any better than a mid-level developer in any of the things they know. Right?
This fallacious logic is exactly why some people prefer specialists over generalists. It results in teams hiring front-end and back-end developers rather than just plain ol’ developers. Because—apparently—only specialists really know what they’re doing.
But here’s the thing:
A generalist was a specialist at some point. A generalist is born when a specialist becomes bored.
In their first job, the generalist is not a generalist. How can they be? They are a novice. However, they do have something that sets them apart from their peers: an appetite to be an expert.
They get to work learning language idioms and patterns. They learn about the language’s performance characteristics, how to communicate with external systems, and explore its library ecosystem. They read all of the books they can find, because they realise that learning didn’t stop when they left college.
In my case it was C#. I was eager to become an expert so I had a whole desk full of books. I was extremely proud of my bookshelf! I read as many open source projects as I could, and even contributed to one or two along the way. I spent a good seven years as a C# developer, and yes—I would like to think I became something of an expert.
But the same learning mindset that drove me to be an expert C# developer also drove me to be something else.
At some point, every expert gets bored. They’ve learned as much as they can about the language and its frameworks. So to feed their appetite, they need to find something new.
With the .NET ecosystem, as a developer with multiple years of experience, if you want to learn new things then you’re basically waiting for Microsoft to release the new version of Visual Studio to see what they’ve tinkered with this time around. Occasionally there are bittersweet moments when Microsoft obsolete some perfectly fine but slightly outdated framework and replace it with something slightly more modern and slightly less robust.
This ‘keeping your knowledge up-to-date’ cycle gets a bit dull when all you know is one language.
So the would-be generalist moves on to something different.
For me it was Ruby. And just wow… how refreshing was Ruby?! No longer at the mercy of Visual Studio! No longer forced to write full function signatures with return types and parameters types! My poor fingers would finally get a break! Dynamic typing… how wonderful! Everything is an expression… amazing! Metaprogramming… incredible! The shackles were off!
I remember this moment as being liberating. While I was appreciative that C# had given me a solid grounding in object-oriented design, I could now also appreciate that it was an unnecessarily complex language. And so I learned to love simplicity.
I’ll tell you my secret weapon for learning new languages: TDD. If you know TDD and a few katas, you can learn just about any language using the same pattern of learning. Just program a few katas and you’ll be off to a flying start. It’s really this simple.
For me, my third language was Clojure, which as languages go is essentially perfect. The Clojure community has the same kind of business-thinking that the .NET community has, balanced with the same desire for simplicity that the Ruby community has.
First comes denial. “This will only be for a short while, then I can go back to real languages.”
The second stage is anger. “React…?! Facebook?! What gave these pesky developers the right to walk all over four decades of GUI development best practice?!”
Then came depression. “My career is over. I’m leaving to set up a beach hut restaurant.”
One of the joys of being a generalist is you stop caring too much about ‘one true way’.
I honestly don’t care too much about the difference between double equals and triple equals, because I know my tests will catch me if I get it wrong.
I do not need a linter to tell me to use semi-colons or not, because I’m happy with either choice. I don’t need a linter to tell me to always return a value from my functions, because I’d rather not have to write extra code if I can avoid it. Ruby and Clojure got me very comfortable with unseen return values.
When something new comes along, I ask myself “Will this new tool|technique|library|framework help me write higher quality code, faster?” If the answer is no, and very often it is no, then I won’t get excited.
Let’s say for the sake of argument that it takes 5 years to become an expert with a language. Then someone with 15 years’ experience will have had time to master 3 languages.
You might say their knowledge of the first two languages will be severely outdated. If they’ve stopped using them professionally they can’t possibly know what they are doing.
That might be true if they completely stopped using that language or keeping abreast of news. But that’s not my experience of generalists. They have their ear to the ground and remain in the loop, and they also tend to be the kinds of people to take a few hours here and there to experiment with the latest and greatest features.
What’s more, if you’ve got 5 years experience in a language, then catching up on the latest framework can mean spending as little as a day to build a toy application. It won’t take a year. Languages and frameworks change only incrementally.
The privilege of being a generalist is that you get to pick the better tool for the job. (I won’t say best tool for the job because who really knows what’s best?)
If the only tool you know is React, then you’re going to get a React solution, even if ‘at scale web applications’ is not your problem.
On my latest project, I’ve had the opportunity to really get to grips with Docker and Nginx. I wouldn’t say I’m an expert, but what I can say is that out of everyone on my team, I’m the one who has been the most eager to jump in and learn it.
My experience as a generalist tells me that as scary, difficult and complicated these tools may seem, I know that it’s possible to master them.
I can see that for some of my teammates learning these tools seems seriously difficult. It will take a huge amount of energy, and they might fail.
There’s no difference in ability between me and my teammates. They are all bright and hard-working. The difference is that I tend to have very little fear of picking up new technologies.
Picking between specialism and generalism is a false dichotomy. If you feel like specializing, then do it. Just don’t forget that beyond specialism lies generalism.
Soft skills are as critical as technical skills for a software engineer. No one works in isolation. Each person has to deal with teammates, colleagues, managers, etc. Therefore team interpersonal skills are essential too. Soft skills include things like good communication, honesty, teamwork, integrity, organization, empathy, etc.